home *** CD-ROM | disk | FTP | other *** search
/ Grand Slam 3 / Grand Slam 3.iso / 023 / soundss3.arj / SBMOD.ASM < prev    next >
Assembly Source File  |  1995-02-11  |  98KB  |  3,968 lines

  1. ;
  2. ;       ╔═══════════════════════════════════════════════╗
  3. ;       ║                                               ║
  4. TITLE   ║ SOUNDBLASTER MODPLAYER  (SB/SBPRO/16 & COMP.) ║
  5. ;       ║                                               ║
  6. ;       ╚═══════════════════════════════════════════════╝
  7. ;
  8. ; THIS MODULE PLAYER WAS CODED IN EARLY 1995
  9. ;
  10. ;                        BY SILVIO TURELLO (FRONTMAN/CREW242)
  11. ;
  12. ; IT IS A COMPLETELY REVISED VERSION OF THE MODLIB
  13. ;
  14. ;                        BY SERGE HUBER (NUMERUS/IMPHOBIA)
  15. ;
  16. ; PC-CONVERSION OF AMIGA PROTRACKER CODE (FOR SUPER PRO PLAY > MODLIB)
  17. ;
  18. ;                        BY JOSHUA C. JENSEN (CYBERSTRIKE/FORM. RENAISSANCE)
  19. ;
  20. ; ORIGIN SOURCE CODE CAME FROM THE PROTRACKER V2.1A
  21. ;
  22. ;                        BY LARS "ZAP" HAMRE (AMIGA FREELANCERS)
  23. ;
  24. ; FEATURES: 4/8-CHANNEL-MODS (M.K./FLT4/FLT8/8CHN), MIXINGRATE 10000-22222 HZ
  25. ;
  26. ;           2/4-FX-CHANNELS, FULL MOD-FX SUPPORT EXCEPT FILTER & REVERSE FUNK
  27. ;
  28. ;           4 TIMES AMPLIFIED (2 BITS HIGHER QUALITY), LINEAR INTERPOLATION
  29. ;
  30. ;           STEREO FOR SBPRO&16, ONLY 15% (APPROX.) PERFORMANCE REDUCTION
  31. ;
  32. ;           656 KB EMS-MEMORY SUPPORT FOR FX
  33. ;
  34. ; MEMORY:   12K CODE, 8K MIXBUF, 16K VOLTABLE, 0-64K TRACKBUF, 0-???K SAMPLES
  35. ;
  36. .ALPHA
  37. .MODEL MEDIUM
  38. COM_OR_OBJ    = 0
  39. STACKLENGTH     = 0100H
  40. UGROUP1 GROUP CODE_SEG1, DATA_SEG1
  41. ASSUME CS:UGROUP1, DS:UGROUP1, SS:UGROUP1
  42. ;=============================================================================
  43. MAX_CHAN_NUMB    = 8
  44. IRQ1            = 20H
  45. IRQ2        = 21H
  46. IRQ3        =0A0H
  47. IRQ4        =0A1H
  48. TIMER0        = 40H
  49. PIT1            = 43H
  50. UHR_INDEX    = 70H
  51. UHR_PORT    = 71H
  52. UHR_STATA    = 0AH
  53. UHR_STATB    = 0BH
  54. UHR_STATC    = 0CH
  55. ;-----------------------------------------------------------------------------
  56. DATA_SEG1 SEGMENT WORD USE16
  57. PROG_START_SEG  DW 0
  58. PROG_END_SEG    DW 0
  59. IF COM_OR_OBJ
  60. VAR_BUFSEG    DW 0
  61. ELSE
  62. VAR_BUFSEG    DW 8000H
  63. ENDIF
  64. SYSTEM        DB 0
  65. IRQCOUNT    DB 56
  66. SBPRO_FLAG    DB 0        ;0=SB, 1= SBPRO
  67. SB_VERSION    DB 1        ;SB=1.0,SBPRO=2.0-3.0,SB16=4.0+
  68. SB_TYP        DB 1        ;0=NO SOUND, 1=SB, 2=SBPRO, 3=GUS, 4=AWE32?
  69. SB_MODUS    DB 0        ;0=MUSIC&FX, 1=MUSIC, 2=FX, 3=NO_SOUND
  70. CD_MIXER    DB 0        ;0=MODULES ONLY, 1=CD MIXED
  71. IRQ_REENTER    DB 0
  72. LOADMOD_FLAG    DB 0
  73. PAN_FX        DB 0        ;FLIP SAMPLE CHANNEL
  74. SAM_FLAG1    DB 0
  75. SAM_FLAG2    DB 0
  76. SAMPLE_RATE    DW 22222
  77. SBP_MIXERI    DW 0224H
  78. SBP_MIXERD    DW 0225H
  79. SB_RESET    DW 0226H
  80. SB_READ        DW 022AH
  81. SB_WRITE    DW 022CH
  82. SB_RSTAT    DW 022EH
  83. IRQ_NUMBER    DB 7
  84. DMA_CHANNEL    DB 1
  85. DMA_RATE    DB 211
  86. DMA_PAGE    DB 0
  87. DMA_POFF    DW 0
  88. DMA_DATA    DB 87H,83H,81H,82H
  89. MAINFREQ    DD 41236
  90. DMA_CX        DW 434
  91. DMA_MORE    DW 434*4
  92. DMA_MAX        DW 434*16
  93. DMA_NEWPTR    DW 0
  94. DMA_PTR        DW 0
  95. DMA_SEG        DW 0
  96. DMA_OFFSET    DW 0
  97. MIXMUL_OFFSET    DW 0
  98. COMP_SPEED2     DW 0106H
  99. COMP_SPEED3     DW 4006H
  100. COMP_SPEED4     DW 0
  101. COMP_SPEED5     DW 1165
  102. HOLD70  LABEL   DWORD
  103.         DW OFFSET TIMER_HANDLER, 0
  104. HOLDSB  LABEL   DWORD
  105.         DW OFFSET SBIRQ_HANDLER, 0
  106. STEREO_PANNING    DW 0,2,0,-2,0,2,0,-2,0
  107. ;-----------------------------------------------------------------------------
  108. GDDLENGTH    DD 0
  109. GDDREST        DW 0
  110. GDDHANDLE    DW 0
  111. GDDZEIG        DB 0
  112. SONG_START    DB 0
  113. ;-----------------------------------------------------------------------------
  114. ERROR1_TEXT    DB "MOD ERROR",13,10,"$"
  115. ERROR2_TEXT    DB "FX ERROR",13,10,"$"
  116. ERROR3_TEXT    DB "SB ERROR",13,10,"$"
  117. OUT_TEXT    DB "+/- VOLUME",13,10
  118.         DB "1   PLAY SAMPLE",13,10
  119.         DB "9   INIT REPEAT",13,10
  120.         DB "0   MUSIC MODE",13,10,"$"
  121. SAMPLE_NAME    DB "SAMPLE1.SAM",0
  122. CONFIG_NAME     DB "SS3.CFG",0
  123. CFG_TEXT1       DB "DEFAULT MUSIC SYSTEM = ",0
  124. CFG_TEXT2       DB "DEFAULT MUSIC MODE = ",0
  125. CFG_TEXT3       DB "SOUNDCARD BASE PORT = ",0
  126. CFG_TEXT4       DB "SOUNDCARD IRQ NUMBER = ",0
  127. CFG_TEXT5       DB "SOUNDCARD DMA NUMBER = ",0
  128. CFG_TEXT6       DB "DEFAULT SAMPLINGRATE = ",0
  129. CFG_TEXT7       DB "SYSTEM COMPATIBILITY = ",0
  130. ;-----------------------------------------------------------------------------
  131. ; PLAYER - KONTROLLSTRUKTUREN
  132. ;-----------------------------------------------------------------------------
  133. ALIGN 2
  134. MUSIC_VOL    DB 255
  135. MUSIC_VOLUME    DB 255
  136. FX_VOL        DB 255
  137. FX_VOLUME    DB 255
  138. MASTER_VOLUME    DB 255
  139. MOD_STAT    DB 0
  140. BPM_RATE    DW 1024
  141. BPM_VALUE    DW 125
  142. BPM_COUNT    DD 0
  143. BPM_SPEED    DD 0
  144. CH_NUMB        DW 4
  145. QUEUE_BUFFER    LABEL    WORD        ;256 BYTES
  146. NOTE        DW MAX_CHAN_NUMB DUP(0)
  147. CMD        DB MAX_CHAN_NUMB DUP(0)
  148. CMDLO        DB MAX_CHAN_NUMB DUP(0)
  149. START        DW MAX_CHAN_NUMB DUP(0)
  150. LENGTHI        DW MAX_CHAN_NUMB DUP(0)
  151. LOOPSTART    DW MAX_CHAN_NUMB DUP(0)
  152. REPLEN        DW MAX_CHAN_NUMB DUP(0)
  153. PERIOD        DW MAX_CHAN_NUMB DUP(0)
  154. FINETUNE    DB MAX_CHAN_NUMB DUP(0)
  155. VOLUME        DB MAX_CHAN_NUMB DUP(0)
  156. TONEPORTDIREC    DB MAX_CHAN_NUMB DUP(1)
  157. TONEPORTSPEED    DB MAX_CHAN_NUMB DUP(0)
  158. WANTEDPERIOD    DW MAX_CHAN_NUMB DUP(0)
  159. VIBRATOCMD    DB MAX_CHAN_NUMB DUP(0)
  160. VIBRATOPOS    DB MAX_CHAN_NUMB DUP(0)
  161. TREMOLOCMD    DB MAX_CHAN_NUMB DUP(0)
  162. TREMOLOPOS    DB MAX_CHAN_NUMB DUP(0)
  163. WAVECONTROL    DB MAX_CHAN_NUMB DUP(0)
  164. GLISSFUNK    DB MAX_CHAN_NUMB DUP(0)
  165. SAMPLEOFFSET    DB MAX_CHAN_NUMB DUP(0)
  166. PATTPOS        DB MAX_CHAN_NUMB DUP(0)
  167. LOOPCOUNT    DB MAX_CHAN_NUMB DUP(0)
  168.  
  169. MFREQ        DW MAX_CHAN_NUMB DUP(0)
  170. MOFLOW        DB MAX_CHAN_NUMB DUP(0)
  171. SONG_DATA    LABEL    BYTE        ;128 BYTES
  172. MVOL        DB MAX_CHAN_NUMB DUP(0)
  173. MSEG        DW MAX_CHAN_NUMB DUP(0)
  174. MOFS        DW MAX_CHAN_NUMB DUP(0)
  175. MREPEAT        DW MAX_CHAN_NUMB DUP(0)
  176. MREPLEN        DW MAX_CHAN_NUMB DUP(0)
  177. MMAXREP        DW MAX_CHAN_NUMB DUP(0)
  178. MOD_NAME    DB 120 DUP(0)        ;MUSS MINDEST. 40 SEIN!
  179. ;-----------------------------------------------------------------------------
  180. ; Seg                           Stores the segment of the current sample.  If
  181. ;                               the segment is zero, then there is no sample
  182. ;                               begin played.
  183. ; Offset                        The current offset of the sample being played
  184. ;                               in the segment specified.
  185. ; MaxRep                        The offset of the place in the sample to
  186. ;                               repeat from (i.e. the end of the sample).
  187. ; Freq                          The frequency to be played out the output
  188. ;                               device.  It is actually a playback period,
  189. ;                               the upper byte determining the number of
  190. ;                               bytes to be added to the sample offset each
  191. ;                               interrupt, and the lower byte to be added
  192. ;                               over and over to generate carry flags to be
  193. ;                               added to additional offsets.
  194. ; Vol                           The actual volume to multiply the frequency
  195. ;                               by.
  196. ; Repeat                        The place to repeat from when the end of the
  197. ;                               loop is found.
  198. ; RepLen                        The number of bytes from Repeat to go to.
  199. ;                               When the end of this is found, it goes back
  200. ;                               to Repeat.
  201. ; OFlow                         The overflow variable used to generate the
  202. ;                               carry flags.
  203. ;-----------------------------------------------------------------------------
  204. ; PROTRACKER VARIABLEN
  205. ;-----------------------------------------------------------------------------
  206. ALIGN 2
  207. MT_SPEED                DB 6
  208. MT_COUNTER              DB 0
  209. MT_PATTERNPOS           DW 0
  210. MT_SONGPOS              DB 0
  211. MT_PATTDELAYTIME2       DB 0
  212. MT_PATTDELAYTIME        DB 0
  213. MT_PBREAKFLAG           DB 0
  214. MT_PBREAKPOS            DB 0
  215. MT_POSJUMPFLAG          DB 0
  216. MT_LOWMASK              DB 0FFH
  217.  
  218. ALIGN 2
  219. Effect_Jump_Table1    LABEL    WORD
  220. DW OFFSET Go_Arpeggio, OFFSET Go_PortaUp, OFFSET Go_PortaDown
  221. DW OFFSET Go_TonePortamento, OFFSET Go_vibrato, OFFSET Go_TonePlusVolSlide
  222. DW OFFSET Go_VibratoPlusVolSlide, OFFSET Go_Tremolo, OFFSET Go_Return
  223. DW OFFSET Go_Return, OFFSET Go_VolumeSlide, OFFSET Go_Return, OFFSET Go_Return
  224. DW OFFSET Go_Return, OFFSET Go_E_Commands, OFFSET Go_Return
  225.  
  226. Effect_Jump_Table2    LABEL    WORD
  227. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  228. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  229. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  230. DW OFFSET Go_SampleOffset, OFFSET Go_PerNop, OFFSET Go_PositionJump
  231. DW OFFSET Go_VolumeChange, OFFSET Go_PatternBreak
  232. DW OFFSET Go_E_Commands, OFFSET Go_SetSpeed
  233.  
  234. Effect_Jump_Table3    LABEL    WORD
  235. DW OFFSET Go_Return, OFFSET Go_FinePortaUp, OFFSET Go_FinePortaDown
  236. DW OFFSET Go_SetGlissControl, OFFSET Go_SetVibratoControl
  237. DW OFFSET Go_SeTFineTune, OFFSET Go_JumpLoop, OFFSET Go_SetTremoloControl
  238. DW OFFSET Go_Return, OFFSET Go_RetrigNote, OFFSET Go_VolumeFineUp
  239. DW OFFSET Go_VolumeFineDown, OFFSET Go_NoteCut, OFFSET Go_NoteDelay
  240. DW OFFSET Go_PatternDelay, OFFSET Go_Return
  241.  
  242. ALIGN 2
  243. MT_VIBRATOTABLE        DB   0, 24, 49, 74, 97,120,141,161
  244.                         DB 180,197,212,224,235,244,250,253
  245.                         DB 255,253,250,244,235,224,212,197
  246.                         DB 180,161,141,120, 97, 74, 49, 24
  247.  
  248. ALIGN 2
  249. MT_PERIODTABLE    LABEL    WORD
  250. DW 856,808,762,720,678,640,604,570,538,508,480,453 ;C-1 to H-1 Finetune +0.
  251. DW 428,404,381,360,339,320,302,285,269,254,240,226 ;C-2 to H-2 Finetune +0.
  252. DW 214,202,190,180,170,160,151,143,135,127,120,113 ;C-3 to H-3 Finetune +0.
  253. DW 107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56 ;C-4 to H-4 Finetune +0.
  254.  
  255. DW 850,802,757,715,674,637,601,567,535,505,477,450 ;C-1 to H-1 Finetune +1.
  256. DW 425,401,379,357,337,318,300,284,268,253,239,225 ;C-2 to H-2 Finetune +1.
  257. DW 213,201,189,179,169,159,150,142,134,126,119,113 ;C-3 to H-3 Finetune +1.
  258. DW 106,100, 94, 89, 84, 79, 75, 71, 67, 83, 59, 56 ;C-4 to H-4 Finetune +1.
  259.  
  260. DW 844,796,752,709,670,632,597,563,532,502,474,447 ;C-1 to H-1 Finetune +2.
  261. DW 422,398,376,355,335,316,298,282,266,251,237,224 ;C-2 to H-2 Finetune +2.
  262. DW 211,199,188,177,167,158,149,141,133,125,118,112 ;C-3 to H-3 Finetune +2.
  263. DW 105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59, 56 ;C-4 to H-4 Finetune +2.
  264.  
  265. DW 838,791,746,704,665,628,592,559,528,498,470,444 ;C-1 to H-1 Finetune +3.
  266. DW 419,395,373,352,332,314,296,280,264,249,235,222 ;C-2 to H-2 Finetune +3.
  267. DW 209,198,187,176,166,157,148,140,132,125,118,111 ;C-3 to H-3 Finetune +3.
  268. DW 104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59, 55 ;C-4 to H-4 Finetune +3.
  269.  
  270. DW 832,785,741,699,660,623,588,555,524,495,467,441 ;C-1 to H-1 Finetune +4.
  271. DW 416,392,370,350,330,312,294,278,262,247,233,220 ;C-2 to H-2 Finetune +4.
  272. DW 208,196,185,175,165,156,147,139,131,124,117,110 ;C-3 to H-3 Finetune +4.
  273. DW 104, 98, 92, 87, 82, 78, 73, 69, 65, 62, 58, 55 ;C-4 to H-4 Finetune +4.
  274.  
  275. DW 826,779,736,694,655,619,584,551,520,491,463,437 ;C-1 to H-1 Finetune +5.
  276. DW 413,390,368,347,328,309,292,276,260,245,232,219 ;C-2 to H-2 Finetune +5.
  277. DW 206,195,184,174,164,155,146,138,130,123,116,109 ;C-3 to H-3 Finetune +5.
  278. DW 103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58, 54 ;C-4 to H-4 Finetune +5.
  279.  
  280. DW 820,774,730,689,651,614,580,547,516,487,460,434 ;C-1 to H-1 Finetune +6.
  281. DW 410,387,365,345,325,307,290,274,258,244,230,217 ;C-2 to H-2 Finetune +6.
  282. DW 205,193,183,172,163,154,145,137,129,122,115,109 ;C-3 to H-3 Finetune +6.
  283. DW 102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57, 54 ;C-4 to H-4 Finetune +6.
  284.  
  285. DW 814,768,725,684,646,610,575,543,513,484,457,431 ;C-1 to H-1 Finetune +7.
  286. DW 407,384,363,342,323,305,288,272,256,242,228,216 ;C-2 to H-2 Finetune +7.
  287. DW 204,192,181,171,161,152,144,136,128,121,114,108 ;C-3 to H-3 Finetune +7.
  288. DW 102, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54 ;C-4 to H-4 Finetune +7.
  289.  
  290. DW 907,856,808,762,720,678,640,604,570,538,504,480 ;C-1 to H-1 Finetune -8.
  291. DW 453,428,404,381,360,339,320,302,285,269,254,240 ;C-2 to H-2 Finetune -8.
  292. DW 226,214,202,190,180,170,160,151,143,135,127,120 ;C-3 to H-3 Finetune -8.
  293. DW 113,107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60 ;C-4 to H-4 Finetune -8.
  294.  
  295. DW 900,850,802,757,715,675,636,601,567,535,505,477 ;C-1 to H-1 Finetune -7.
  296. DW 450,425,401,379,357,337,318,300,284,268,253,238 ;C-2 to H-2 Finetune -7.
  297. DW 225,212,200,189,179,169,159,150,142,134,126,119 ;C-3 to H-3 Finetune -7.
  298. DW 112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59 ;C-4 to H-4 Finetune -7.
  299.  
  300. DW 894,844,796,752,709,670,632,597,563,532,502,474 ;C-1 to H-1 Finetune -6.
  301. DW 447,422,398,376,355,335,316,298,282,266,251,237 ;C-2 to H-2 Finetune -6.
  302. DW 223,211,199,188,177,167,158,149,141,133,125,118 ;C-3 to H-3 Finetune -6.
  303. DW 111,105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -6.
  304.  
  305. DW 887,838,791,746,704,665,628,592,559,528,498,470 ;C-1 to H-1 Finetune -5.
  306. DW 444,419,395,373,352,332,314,296,280,264,249,235 ;C-2 to H-2 Finetune -5.
  307. DW 222,209,198,187,176,166,157,148,140,132,125,118 ;C-3 to H-3 Finetune -5.
  308. DW 111,104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -5.
  309.  
  310. DW 881,832,785,741,699,660,623,588,555,524,494,467 ;C-1 to H-1 Finetune -4.
  311. DW 441,416,392,370,350,330,312,294,278,262,247,233 ;C-2 to H-2 Finetune -4.
  312. DW 220,208,196,185,175,165,156,147,139,131,123,117 ;C-3 to H-3 Finetune -4.
  313. DW 110,104, 98, 92, 87, 82, 78, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -4.
  314.  
  315. DW 875,826,779,736,694,655,619,584,551,520,491,463 ;C-1 to H-1 Finetune -3.
  316. DW 437,413,390,368,347,338,309,292,276,260,245,232 ;C-2 to H-2 Finetune -3.
  317. DW 219,206,195,184,174,164,155,146,138,130,123,116 ;C-3 to H-3 Finetune -3.
  318. DW 109,103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -3.
  319.  
  320. DW 868,820,774,730,689,651,614,580,547,516,487,460 ;C-1 to H-1 Finetune -2.
  321. DW 434,410,387,365,345,325,307,290,274,258,244,230 ;C-2 to H-2 Finetune -2.
  322. DW 217,205,193,183,172,163,154,145,137,129,122,115 ;C-3 to H-3 Finetune -2.
  323. DW 108,102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57 ;C-4 to H-4 Finetune -2.
  324.  
  325. DW 862,814,768,725,684,646,610,575,543,513,484,457 ;C-1 to H-1 Finetune -1.
  326. DW 431,407,384,363,342,323,305,288,272,256,242,228 ;C-2 to H-2 Finetune -1.
  327. DW 216,203,192,181,171,161,152,144,136,128,121,114 ;C-3 to H-3 Finetune -1.
  328. DW 108,101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57 ;C-4 to H-4 Finetune -1.
  329. ;-----------------------------------------------------------------------------
  330. ; MTM - TRACKSTRUKTUR
  331. ;-----------------------------------------------------------------------------
  332. ALIGN 2
  333. TRACK_NUMBER    DW 0
  334. TRACK_INFO    DB 8 DUP(0)
  335. TRACK_SEG    DW 0
  336. TRACKS_OFFSET    DW OFFSET TRACK1_DATA, OFFSET TRACK2_DATA, OFFSET TRACK3_DATA
  337.         DW OFFSET TRACK4_DATA, OFFSET TRACK5_DATA, OFFSET TRACK6_DATA
  338.         DW OFFSET TRACK7_DATA, OFFSET TRACK8_DATA
  339. TRACK1_DATA    DB 128 DUP(0)
  340. TRACK2_DATA    DB 128 DUP(0)
  341. TRACK3_DATA    DB 128 DUP(0)
  342. TRACK4_DATA    DB 128 DUP(0)
  343. TRACK5_DATA    DB 128 DUP(0)
  344. TRACK6_DATA    DB 128 DUP(0)
  345. TRACK7_DATA    DB 128 DUP(0)
  346. TRACK8_DATA    DB 128 DUP(0)
  347. ;-----------------------------------------------------------------------------
  348. ; MOD - DATEISTRUKTUR
  349. ;-----------------------------------------------------------------------------
  350. ALIGN 2
  351. SAMPLE_SIZE    DW 0
  352. PATTERN_SIZE    DW 0
  353. PATTERN_SEG    DW 0
  354. PATTERN_NUMBER    DW 0
  355. PATTERN_CURRENT    DW 0
  356. ISIZE        DW 31 DUP(0)
  357. IVOL_FINETUNE    DW 31 DUP(0)
  358. ILOOP_START    DW 31 DUP(0)
  359. ILOOP_SIZE    DW 31 DUP(0)
  360. SONG_SIZE    DB 0
  361. SONG_LOOP    DB 0
  362. MOD_SIGN    DD 0
  363. SAMPLE_SEG    DW 31 DUP(0)
  364. ;-----------------------------------------------------------------------------
  365. ; SINGLE SAMPLE VARIABLES
  366. ;-----------------------------------------------------------------------------
  367. SAMPLE_ZEIG    DW 0
  368. SAMPLE_MEM    DW 64 DUP(0)
  369. SAMPLE_BIG    DW 64 DUP(0)
  370. EMS_SEG        DW 0
  371. EMS_OFFSET    DW 0
  372. EMS_HANDLE    DW 0
  373. SAM_SEG1    DW 0
  374. SAM_SEG2    DW 0
  375. SAM_SEG3    DW 0
  376. SAM_SEG4    DW 0
  377. SAM_OFS1    DD 0
  378. SAM_OFS2    DD 0
  379. SAM_OFS3    DD 0
  380. SAM_OFS4    DD 0
  381. SAM_FRQ1    DW 0
  382. SAM_FRQ2    DW 0
  383. SAM_FRQ3    DW 0
  384. SAM_FRQ4    DW 0
  385. SAM_OFL1    DB 0
  386. SAM_OFL2    DB 0
  387. SAM_OFL3    DB 0
  388. SAM_OFL4    DB 0
  389. SAM_MAX1    DW 0
  390. SAM_MAX2    DW 0
  391. SAM_MAX3    DW 0
  392. SAM_MAX4    DW 0
  393. ;-----------------------------------------------------------------------------
  394. PROG_END        LABEL   BYTE    ;MUSS LETZE ZEILE IM DATENSEGMENT SEIN!
  395. ;-----------------------------------------------------------------------------
  396. DATA_SEG1 ENDS
  397.  
  398. .386
  399. CODE_SEG1 SEGMENT PAGE USE16
  400. ORG 100H
  401. ;=============================================================================
  402. PUBLIC _MAIN1
  403. _MAIN1 PROC FAR
  404.     JMP    MAIN_CONT        ;0100
  405.     RETF
  406.     CALL    CONFIG_INIT        ;0104
  407.     RETF
  408.     CALL    LOAD_MOD        ;0108
  409.     RETF
  410.     CALL    PLAY_MUSIC        ;010C
  411.     RETF
  412.     CALL    STOP_MUSIC        ;0110
  413.     RETF
  414.     CALL    END_MUSIC        ;0114
  415.     RETF
  416.     CALL    LOAD_SAMPLE        ;0118
  417.     RETF
  418.     CALL    PLAY_SAMPLE        ;011C
  419.     RETF
  420.     CALL    END_SAMPLE        ;0120
  421.     RETF
  422.     CALL    SET_SAMPLERATE        ;0124
  423.     RETF
  424.     CALL    GET_VOLUME        ;0128
  425.     RETF
  426.     CALL    SET_VOLUME        ;012C
  427.     RETF
  428.     CALL    SET_SONGLOOP        ;0130
  429.     RETF
  430.     CALL    GET_SONGPOSITION    ;0134
  431.     RETF
  432.     CALL    SET_SONGPOSITION    ;0138
  433.     RETF
  434.     CALL    GET_SONGMOD        ;013C
  435.     RETF
  436.     CALL    SET_SONGMOD        ;0140
  437.     RETF
  438.     CALL    DSP_OFF            ;0144
  439.     RETF
  440.     CALL    DSP_RESET        ;0148
  441.     RETF
  442. _MAIN1 ENDP
  443. ;=============================================================================
  444. ;
  445. ; MOD ROUTINEN
  446. ;
  447. ;=============================================================================
  448. ; Format of a note: (ORIGINALLY MOD)
  449. ;
  450. ;                   0 0          0 0          0 0           0 0
  451. ;                   | |          | |          | |           | |
  452. ;                  /   \        / /          /   \           \ \
  453. ;         MSB of Ins.     Note        LSB Ins.  Spec. Com.   Data for special
  454. ;
  455. ; Format of a note: (MODIFIED BY LOADER)
  456. ;
  457. ;                   0 0          0 0          0 0           0 0
  458. ;                   | |          | |          | |           | |
  459. ;                  / /          /   \         \ \           \ \
  460. ;            LSB NOTE   SPEC.COM.    MSB NOTE  INSTRUMENT    DATA FOR SPECIAL
  461. ;
  462. ;╒═══════════════════════════════════════════════════════════════════════════╕
  463. ;│ DESCRIPTION: This procedure shouldn't need to be called by anything else  │
  464. ;│              but the interrupt (ever).  It handles all note updating,     │
  465. ;│              special effects, pointers, etc.                              │
  466. ;│                                                                           │
  467. ;│              *** This code came directly from the Amiga Protracker        │
  468. ;│                  playback code, written by Lars "Zap" Hamre.  Give this   │
  469. ;│                  guy a pat on the back for such excellent code.           │
  470. ;│                                                                           │
  471. ;│ BUGS       : Or rather, non-implementations.  Command EF - Funk it is     │
  472. ;│              not all the way implemented.  Command E0 - Filter is not     │
  473. ;│              implemented at all.  It is Amiga-specific, directly with     │
  474. ;│              the Paula chip.                                              │
  475. ;│                                                                           │
  476. ;│ IMPROVEMENTS:    Optimized code for PC-architecure by the Frontman        │
  477. ;│                                                                           │
  478. ;╘═══════════════════════════════════════════════════════════════════════════╛
  479. CONTROL_CHANNELS PROC NEAR
  480.     CMP    LOADMOD_FLAG,0
  481.     JNE    Go_NoNewPosYet
  482.     CMP    MOD_STAT,3
  483.     JAE    Go_NoNewPosYet
  484.     INC    MT_COUNTER
  485.     MOV    AL,MT_COUNTER
  486.     CMP    AL,MT_SPEED        ; Does it match the current speed?
  487.     JB    SHORT Go_NoNewNote    ; No, just do fx.
  488.     MOV    MT_COUNTER,0
  489.     CMP    MT_PATTDELAYTIME2,0
  490.     JE    SHORT Go_GetNewNote
  491.         CALL    Go_CheckEfx        ; Otherwise, just do fx only.
  492.         JMP    Go_Dskip                ; Then, jump to update block values.
  493. Go_NoNewNote:
  494.     CALL    Go_CheckEfx        ; Do fx.
  495.         JMP    Go_NoNewPosYet        ; We don't update block values
  496.                     ; when we are just doing fx.
  497. Go_GetNewNote:
  498.     MOV    ES,TRACK_SEG
  499.     XOR    SI,SI
  500. Go_PlayVoice:
  501.     PUSH    SI
  502.     MOV    DI,SI
  503.     SHL    DI,1
  504.     MOVZX    BX,MT_SONGPOS        ; BLOCK BEGINNING TO ES:BX
  505.     ADD    BX,[TRACKS_OFFSET+DI]
  506.     MOVZX    BX,[BX]
  507.     XCHG    BL,BH            ; MULTIPLY WITH 256 (TRACK-SIZE)
  508.     ADD    BX,MT_PATTERNPOS
  509.     CMP    [NOTE+DI],0        ; See if there is a note.
  510.     JNE    SHORT Go_plvskip    ; No, go on.
  511.     CMP    [CMD+SI],0
  512.     JNE    SHORT Go_plvskip
  513.     CMP    [CMDLO+SI],0
  514.     JNE    SHORT Go_plvskip
  515.     CALL    Go_PerNop        ; Otherwise, figure out the frequency.
  516. Go_plvskip:
  517.     MOV    AX,ES:[BX]        ; Load this channel's information
  518.     MOV    [NOTE+DI],AX        ; from the actual track block and
  519.     AND    [NOTE+DI],0FFFH
  520.     SHR    AH,4            ; into our own internal structure
  521.     MOV    [CMD+SI],AH        ; to access it from.
  522.     MOV    AX,ES:[BX+2]
  523.     MOV    [CMDLO+SI],AH
  524.     OR    AL,AL            ; Instrument byte.  Is there an ins?
  525.     JZ    SHORT Go_SetRegs
  526.     DEC    AL
  527.     MOVZX    BX,AL            ; GET SAMPLE SEGMENT
  528.     SHL    BX,1
  529.     MOV    AX,[SAMPLE_SEG+BX]
  530.     MOV    [START+DI],AX        ; Store it in our structure.
  531.     MOV    AX,[ISIZE+BX]        ; Get the length.
  532.     MOV    [LENGTHI+DI],AX        ; Store it appropriately.
  533.     MOV    AX,[IVOL_FINETUNE+BX]    ; Get the instrument volume and fine tune.
  534.     MOV    [VOLUME+SI],AL        ; Store it appropriately.
  535.     MOV    [FINETUNE+SI],AH
  536.     MOV    [MVOL+SI],AL
  537.     MOV    CX,[ILOOP_SIZE+BX]    ; Get Repeat length
  538.     CMP    CX,8            ; If the length is less than four,
  539.     JB    SHORT Go_NoLoop        ; then there is no loop.
  540.     MOV    AX,[ILOOP_START+BX]    ; Get the Repeat start.
  541.     MOV    [MREPEAT+DI],AX        ; Move it into the appropriate
  542.     MOV    [LOOPSTART+DI],AX    ; structures and locations.
  543.     MOV    [REPLEN+DI],CX        ; Move the length into its storage.
  544.     ADD    AX,CX            ; We're figuring out the offset of
  545.     MOV    [MREPLEN+DI],AX
  546.     MOV    [MMAXREP+DI],AX        ; where the repeat length breaks.
  547.     JMP    SHORT Go_SetRegs    ; Skip the no loop part.
  548. Go_NoLoop:
  549.     XOR    AX,AX            ; Zero out AX.
  550.     MOV    [REPLEN+DI],AX
  551.     MOV    [MREPLEN+DI],AX        ; Make sure that no loop exists and
  552.     MOV    [MREPEAT+DI],AX
  553.     MOV    [LOOPSTART+DI],AX
  554. Go_SetRegs:
  555.     CMP    [NOTE+DI],0        ; Grab the note.
  556.     JE    Go_CheckMore        ; Check the fx.
  557.     MOV    AH,[CMD+SI]        ; Get the special fx command.
  558.     MOV    AL,[CMDLO+SI]
  559.     AND    AL,0F0H            ; Mask out the bits we don't want.
  560.     CMP    AX,0E50H        ; Is there a fine tune command
  561.     JE    SHORT Go_DoSetFineTune
  562.     CMP    AH,3            ; Is it a tone portamento?
  563.     JE    SHORT Go_ChkTonePorta
  564.     CMP    AH,5            ; Is it a tone and volume slide?
  565.     JE    SHORT Go_ChkTonePorta
  566.     CMP    AH,9            ; Is it a sample offset command?
  567.     JNE    SHORT Go_SetPeriod    ; If not, go do the actual note.
  568.     PUSH    AX            ; keep the command byte in mem
  569.     CALL    Go_CheckMoreEfx
  570.     POP    AX
  571.     JMP    SHORT Go_SetPeriod    ; Go do the actual note.
  572. Go_ChkTonePorta:
  573.     CALL    Go_SetTonePorta        ; Do part of the tone portamento.
  574.     JMP    Go_CheckMore        ; Go do the fx.
  575. Go_DoSetFineTune:
  576.     PUSH    AX
  577.     MOV    AL,[CMDLO+SI]
  578.     AND    AL,0FH
  579.     CALL    Go_SetFineTune        ; Update the fine tune.
  580.     POP    AX
  581. ;-----------------------------------------------------------------------------
  582. ; ──── We are now going to find the note in the period table.  If it
  583. ; ──── doesn't exist, then no fine tuning can be performed.  If it
  584. ; ──── does, and fine tuning is specified, then we can update it.
  585. ;-----------------------------------------------------------------------------
  586. Go_SetPeriod:
  587.     MOV    CL,AH
  588.     MOV    AX,[NOTE+DI]        ; Get the note.
  589.     DEC    AX
  590.     MOV    BX,OFFSET MT_PERIODTABLE; Set pointer to beginning of table.
  591.     CMP    CL,3
  592.     JE    SHORT Seek_Period
  593.     CMP    CL,5
  594.     JNE    SHORT Go_ftufound
  595. Seek_Period:
  596.     INC    AX
  597.     MOV    CX,36+12        ; 36 periods to cycle through.
  598. Go_ftuloop:
  599.     CMP    AX,[BX]            ; Check the note against the period.
  600.     JAE    SHORT Go_Wizzyfound    ; We found it!
  601.     INC    BX
  602.     INC    BX            ; Otherwise, update the pointer and
  603.     LOOP    Go_ftuloop        ; keep looping.
  604.     JMP    SHORT Go_Wizzyfound
  605. Go_ftufound:
  606.     ADD    BX,AX
  607. Go_WizzyFound:
  608.     MOV    AL,[FINETUNE+SI]    ; Get the fine tune.
  609.     MOV    CL,(36+12)*2        ; The period table's size is 72.
  610.     MUL    CL            ; Multiply it by the fine tune.
  611.     ADD    BX,AX            ; Add it onto the pointer to point to
  612.     MOV    AX,[BX]            ; the new period and get it.
  613.     MOV    [PERIOD+DI],AX        ; Store it.
  614.     MOV    AH,[CMD+SI]        ; Get the special fx command.
  615.     MOV    AL,[CMDLO+SI]
  616.     AND    AL,0F0H            ; Mask out the bits we don't want.
  617.     CMP    AX,0ED0H
  618.     JE    SHORT Go_delnoc
  619.     MOV    AL,[WAVECONTROL+SI]    ; Get the WaveControl.
  620.     TEST    AL,00000100B        ; Amiga: BTST #2,WaveControl.
  621.     JZ    SHORT Go_vibnoc        ; If it is zero, then skip.
  622.     MOV    [VIBRATOPOS+SI],0
  623. Go_vibnoc:
  624.     TEST    AL,01000000B        ; Amiga: BTST #6,WaveControl
  625.     JZ    SHORT Go_trenoc        ; If it is zero, then skip.
  626.     MOV    [TREMOLOPOS+SI],0    ; Zero the Tremolo offset.
  627. Go_trenoc:
  628.     MOV    AX,[START+DI]        ; Get the start segment.
  629.     MOV    [MSEG+DI],AX        ; Store it to be updated.
  630.     MOV    [MOFS+DI],0        ; Set the offset to zero.
  631.     MOV    [MOFLOW+SI],0
  632.     MOV    AX,[LENGTHI+DI]
  633.     MOV    [MMAXREP+DI],AX        ; Store in MaxRepeat
  634.     MOV    CX,[PERIOD+DI]
  635.     CALL    Go_PerNop2
  636.     JMP    SHORT Go_CheckMore
  637. Go_delnoc:
  638.     MOV    AX,[MMAXREP+DI]
  639.     MOV    [MOFS+DI],AX
  640. Go_CheckMore:
  641.     CALL    Go_CheckMoreEfx
  642. Go_DoNext:
  643.     POP    SI            ;SKIP TO NEXT CHANNEL
  644.     INC    SI
  645.     CMP    SI,CH_NUMB
  646.     JB    Go_PlayVoice
  647. ;-----------------------------------------------------------------------------
  648. Go_Dskip:
  649.     ADD    MT_PATTERNPOS,4        ; Increment position by one
  650.     MOV    AL,MT_PATTDELAYTIME
  651.     OR    AL,AL
  652.     JZ    SHORT Go_dskc
  653.     MOV    MT_PATTDELAYTIME2,AL
  654.     MOV    MT_PATTDELAYTIME,0
  655. Go_dskc:
  656.     CMP    MT_PATTDELAYTIME2,0
  657.     JE    SHORT Go_dska
  658.     DEC    MT_PATTDELAYTIME2
  659.     JZ    SHORT Go_dska
  660.     SUB    MT_PATTERNPOS,4
  661. Go_dska:
  662.     CMP    MT_PBREAKFLAG,0
  663.     JE    SHORT Go_nnpysk
  664.     MOV    MT_PBREAKFLAG,0
  665.     MOVZX    AX,MT_PBREAKPOS
  666.     MOV    MT_PBREAKPOS,AH
  667.     SHL    AX,2
  668.     MOV    MT_PATTERNPOS,AX
  669. Go_nnpysk:
  670.     CMP    MT_PATTERNPOS,256
  671.     JB    SHORT Go_NoNewPosYet
  672. Go_NextPosition:
  673.     MOVZX    AX,MT_PBREAKPOS
  674.     SHL    AX,2
  675.     MOV    MT_PATTERNPOS,AX
  676.     MOV    MT_PBREAKPOS,0
  677.     MOV    MT_POSJUMPFLAG,0
  678.     MOV    AL,MT_SONGPOS
  679.     INC    AL
  680.     AND    AL,7FH
  681.     MOV    MT_SONGPOS,AL
  682.     CMP    AL,SONG_SIZE
  683.     JB    SHORT Go_NoNewPosYet
  684.     MOV    AL,SONG_LOOP
  685.     CMP    AL,SONG_SIZE
  686.     JB    SHORT Go_NoSongRestart
  687.     MOV    MOD_STAT,3
  688.     XOR    AL,AL
  689. Go_NoSongRestart:
  690.     MOV    MT_SONGPOS,AL
  691.     MOV    MT_SPEED,6        ;DEFAULT PROTRACKER SPEED
  692.     MOV    MT_COUNTER,0        ;RESET PROTRACKER VARIABLES
  693.     MOV    AL,125
  694.     CALL    Go_SetBPM
  695.     MOV    BPM_COUNT,0
  696. Go_NoNewPosYet:
  697.     CMP    MT_POSJUMPFLAG,0
  698.     JNE    Go_NextPosition
  699.     RET
  700. CONTROL_CHANNELS ENDP
  701. ;=============================================================================
  702. Go_CheckEfx PROC NEAR
  703.     XOR    SI,SI
  704. Go_DoEfx:
  705.     PUSH    SI
  706.     MOV    DI,SI
  707.     SHL    DI,1
  708.     MOV    BL,[CMD+SI]              ; Get the special command
  709.     MOV    BH,[CMDLO+SI]
  710.     OR    BX,BX
  711.     JNZ    SHORT SetBack1
  712.     CALL    Go_PerNop
  713.     JMP    SHORT SetBack2
  714. SetBack1:
  715.     XOR    BH,BH
  716.     SHL    BX,1
  717.     CALL    [Effect_Jump_Table1+BX]
  718. SetBack2:
  719.     POP    SI
  720.     INC    SI
  721.     CMP    SI,CH_NUMB
  722.     JB    Go_DoEfx
  723. Go_Return:
  724.     RET
  725. ;-----------------------------------------------------------------------------
  726. Go_PerNop PROC NEAR
  727.     MOV    CX,[PERIOD+DI]
  728. Go_PerNop2 PROC NEAR
  729.     XOR    AX,AX
  730.     JCXZ    SHORT Go_DivZero
  731.     MOV    AX,WORD PTR MAINFREQ
  732.     MOV    DX,WORD PTR MAINFREQ+2
  733.     DIV    CX
  734. Go_DivZero:
  735.     MOV    [MFREQ+DI],AX
  736.     RET
  737. Go_PerNop2 ENDP
  738. Go_PerNop ENDP
  739. Go_CheckEfx ENDP
  740. ;=============================================================================
  741. ;
  742. ; SI IS THE CHANNEL-BYTE-INDEX, DI IS THE CHANNEL-WORD-INDEX
  743. ;
  744. ;─────────────────────────────────────────────────────────────────────────────
  745. ; Effect 0 -- Arpeggio
  746. ;─────────────────────────────────────────────────────────────────────────────
  747. Go_Arpeggio PROC NEAR
  748.     MOVZX    AX,MT_COUNTER
  749.     MOV    BL,3
  750.     MOV    CX,[PERIOD+DI]
  751.     DIV    BL
  752.     OR    AH,AH
  753.     JZ    SHORT Go_Arpeggio1
  754.     MOV    AL,[CMDLO+SI]
  755.     CMP    AH,2
  756.     JE    SHORT Go_Arpeggio2
  757.     SHR    AL,4
  758. Go_Arpeggio2:
  759.     AND    AL,0FH
  760.     SHL    AL,1
  761.     MOVZX    BX,AL
  762.     MOV    AL,[FINETUNE+SI]
  763.     MOV    DX,CX
  764.     MOV    CL,(36+12)*2
  765.     MUL    CL
  766.     PUSH    DI
  767.     MOV    DI,OFFSET MT_PERIODTABLE
  768.     ADD    DI,AX
  769.     MOV    AH,36+12
  770. Go_arploop:
  771.     MOV    CX,[BX+DI]
  772.     CMP    DX,[DI]
  773.     JAE    SHORT Go_arpafterloop
  774.         INC    DI
  775.     INC    DI
  776.     DEC    AH
  777.     JNZ    Go_arploop
  778.     POP    DI
  779.     RET
  780. Go_arpafterloop:
  781.     POP    DI
  782. Go_Arpeggio1:
  783.     CALL    Go_PerNop2
  784.         RET
  785. Go_Arpeggio ENDP
  786. ;─────────────────────────────────────────────────────────────────────────────
  787. ; Effect 1 -- Portamento Up
  788. ;─────────────────────────────────────────────────────────────────────────────
  789. Go_PortaUp PROC NEAR
  790.     MOVZX    AX,[CMDLO+SI]        ; Number to slide up (was lo)
  791.     AND    AL,MT_LOWMASK
  792.     MOV    MT_LOWMASK,0FFH
  793.     SUB    [PERIOD+DI],AX
  794.     MOV    CX,[PERIOD+DI]
  795.     CMP    CX,113
  796.     JGE    SHORT Go_PortaUSkip
  797.     MOV    CX,113
  798.     MOV    [PERIOD+DI],CX
  799. Go_PortaUSkip:
  800.     CALL    Go_PerNop2
  801.     RET
  802. Go_PortaUp ENDP
  803. ;────────────────────────────────────────────────────────────────────────────
  804. ; Effect 2 -- Portamento Down
  805. ;────────────────────────────────────────────────────────────────────────────
  806. Go_PortaDown PROC NEAR
  807.     MOVZX    AX,[CMDLO+SI]        ; Number to slide down
  808.     AND    AL,MT_LOWMASK
  809.     MOV    MT_LOWMASK,0FFH
  810.     ADD    [PERIOD+DI],AX
  811.     MOV    CX,[PERIOD+DI]
  812.     CMP    CX,856
  813.     JL    SHORT Go_PortaDSkip
  814.     MOV    CX,856
  815.     MOV    [PERIOD+DI],CX
  816. Go_PortaDSkip:
  817.     CALL    Go_PerNop2
  818.     RET
  819. Go_PortaDown ENDP
  820. ;────────────────────────────────────────────────────────────────────────────
  821. ; Effect 3 -- Tone Portamento
  822. ;────────────────────────────────────────────────────────────────────────────
  823. Go_TonePortamento PROC NEAR
  824.     MOV    AL,[CMDLO+SI]
  825.     OR    AL,AL
  826.     JZ    SHORT Go_TonePortNoChange
  827.     MOV    [TONEPORTSPEED+SI],AL
  828.     MOV    [CMDLO+SI],0
  829. Go_TonePortNoChange:
  830.     CMP    [WANTEDPERIOD+DI],0
  831.     JZ    Go_Return
  832.     MOVZX    DX,[TONEPORTSPEED+SI]
  833.     MOV    CX,[PERIOD+DI]
  834.     MOV    AX,[WANTEDPERIOD+DI]
  835.     CMP    [TONEPORTDIREC+SI],0
  836.     JNE    SHORT Go_TonePortaUp
  837. Go_TonePortaDown:
  838.     ADD    CX,DX
  839.     CMP    AX,CX
  840.     JG    SHORT Go_TonePortaSetPer
  841.     JMP    SHORT Go_TonePortaEnd
  842. Go_TonePortaUp:
  843.     SUB    CX,DX
  844.     CMP    AX,CX
  845.     JL    SHORT Go_TonePortaSetPer
  846. Go_TonePortaEnd:
  847.     MOV    CX,AX
  848.     MOV    [WANTEDPERIOD+DI],0
  849. Go_TonePortaSetPer:
  850.     MOV    [PERIOD+DI],CX
  851.     MOV    AL,[GLISSFUNK+SI]
  852.     AND    AL,0FH
  853.     JZ    SHORT Go_GlissSkip
  854.     MOV    AL,[FINETUNE+SI]
  855.     MOV    BL,(36+12)*2
  856.     MUL    BL
  857.     PUSH    DI
  858.     MOV    DI,OFFSET MT_PERIODTABLE
  859.     ADD    DI,AX
  860.     XOR    BX,BX
  861. Go_GlissLoop:
  862.     CMP    CX,[BX+DI]
  863.     JAE    SHORT Go_GlissFound
  864.     INC    BX
  865.     INC    BX
  866.     CMP    BX,(36+12)*2
  867.     JB    Go_GlissLoop
  868.     MOV    BX,(35+12)*2
  869. Go_GlissFound:
  870.     MOV    CX,[BX+DI]
  871.     POP    DI
  872. Go_GlissSkip:
  873.     CALL    Go_PerNop2
  874.     RET
  875. Go_TonePortamento ENDP
  876. ;-----------------------------------------------------------------------------
  877. Go_SetTonePorta PROC NEAR
  878.     MOV    DX,[NOTE+DI]
  879.     MOV    AL,[FINETUNE+SI]
  880.     MOV    CL,48*2            ;37
  881.     MUL    CL
  882.     PUSH    DI
  883.     MOV    DI,OFFSET MT_PERIODTABLE
  884.     ADD    DI,AX
  885.     XOR    BX,BX
  886. Go_StpLoop:
  887.     CMP    DX,[BX+DI]
  888.     JAE    SHORT Go_StpFound
  889.     INC    BX
  890.     INC    BX
  891.     CMP    BX,48*2            ;37
  892.     JB    Go_StpLoop
  893.     MOV    BX,47*2            ;35
  894. Go_StpFound:
  895.     MOV    DL,[FINETUNE+SI]
  896.     AND    DL,8
  897.     JZ    SHORT Go_StpGoss
  898.     OR    BX,BX
  899.     JZ    SHORT Go_StpGoss
  900.     DEC    BX
  901.     DEC    BX
  902. Go_StpGoss:
  903.     MOV    DX,[BX+DI]
  904.     POP    DI
  905.     MOV    [WANTEDPERIOD+DI],DX
  906.     MOV    AX,[PERIOD+DI]
  907.     MOV    [TONEPORTDIREC+SI],0
  908.     CMP    DX,AX
  909.     JE    SHORT Go_ClearTonePorta
  910.     JA    Go_Return
  911.     INC    [TONEPORTDIREC+SI]
  912.     RET
  913. Go_ClearTonePorta:
  914.     MOV    [WANTEDPERIOD+DI],0
  915.     RET
  916. Go_SetTonePorta ENDP
  917. ;────────────────────────────────────────────────────────────────────────────
  918. ; Effect 4 -- Vibrato
  919. ;────────────────────────────────────────────────────────────────────────────
  920. Go_Vibrato PROC NEAR
  921.     MOV    AL,[CMDLO+SI]
  922.     OR    AL,AL
  923.     JZ    SHORT Go_Vibrato2
  924.     MOV    BL,[VIBRATOCMD+SI]
  925.     AND    AL,0FH
  926.     JZ    SHORT Go_vibskip
  927.     AND    BL,0F0H
  928.     OR    BL,AL
  929. Go_vibskip:
  930.     MOV    AL,[CMDLO+SI]
  931.     AND    AL,0F0H
  932.     JZ    SHORT Go_vibskip2
  933.     AND    BL,0FH
  934.     OR    BL,AL
  935. Go_vibskip2:
  936.     MOV    [VIBRATOCMD+SI],BL
  937. Go_Vibrato2:
  938.     MOV    AL,[VIBRATOPOS+SI]
  939.     SHR    AL,2
  940.     AND    AX,1FH
  941.     MOV    BL,[WAVECONTROL+SI]
  942.     AND    BL,3
  943.     JZ    SHORT Go_vib_sine
  944.     SHL    AL,3
  945.     CMP    BL,1
  946.     JE    SHORT Go_vib_rampdown
  947.     MOV    BL,255
  948.     JMP    SHORT Go_vib_set
  949. Go_vib_rampdown:
  950.     CMP    [VIBRATOPOS+SI],0
  951.     JG    SHORT Go_vib_rampdown2
  952.     MOV    BL,AL
  953.     NOT    BL
  954.     JMP    SHORT Go_vib_set
  955. Go_vib_rampdown2:
  956.     MOV    BL,AL
  957.     JMP    SHORT Go_vib_set
  958. Go_vib_sine:
  959.     MOVZX    BX,AL
  960.     MOV    BL,[MT_VIBRATOTABLE+BX]
  961. Go_vib_set:
  962.     MOV    AL,[VIBRATOCMD+SI]
  963.     AND    AL,0FH
  964.     MUL    BL
  965.     SHR    AX,7
  966.     MOV    BX,AX
  967.     MOV    AX,[PERIOD+DI]
  968.     CMP    [VIBRATOPOS+SI],0
  969.     JG    SHORT Go_VibratoNeg    ; BMI
  970.     NEG    BX
  971. Go_VibratoNeg:
  972.     ADD    AX,BX
  973. Go_Vibrato3:
  974.     MOV    CX,AX
  975.     CALL    Go_PerNop2
  976.     MOV    AL,[VIBRATOCMD+SI]
  977.     AND    AL,0F0H
  978.     SHR    AL,2
  979.     ADD    [VIBRATOPOS+SI],AL
  980.     RET
  981. Go_Vibrato ENDP
  982. ;────────────────────────────────────────────────────────────────────────────
  983. ; Effect 5 -- Tone and Volume Slide
  984. ;────────────────────────────────────────────────────────────────────────────
  985. Go_TonePlusVolSlide PROC NEAR
  986.     CALL    Go_TonePortNoChange
  987.     JMP    Go_VolumeSlide
  988. Go_TonePlusVolSlide ENDP
  989. ;────────────────────────────────────────────────────────────────────────────
  990. ; Effect 6 -- Vibrato and Volume Slide
  991. ;────────────────────────────────────────────────────────────────────────────
  992. Go_VibratoPlusVolSlide PROC NEAR
  993.     CALL    Go_Vibrato2        ;was mt_vibrato2
  994.     JMP    Go_VolumeSlide
  995. Go_VibratoPlusVolSlide ENDP
  996. ;────────────────────────────────────────────────────────────────────────────
  997. ; Effect 7 -- Tremolo
  998. ;────────────────────────────────────────────────────────────────────────────
  999. Go_Tremolo PROC NEAR
  1000.     MOV    AL,[CMDLO+SI]
  1001.     OR    AL,AL
  1002.     JZ    SHORT Go_Tremolo2
  1003.     MOV    BL,[TREMOLOCMD+SI]
  1004.     AND    AL,0FH
  1005.     JZ    SHORT Go_treskip
  1006.     AND    BL,0F0H
  1007.     OR    BL,AL
  1008. Go_treskip:
  1009.     MOV    AL,[CMDLO+SI]
  1010.     AND    AL,0F0H
  1011.     JZ    SHORT Go_treskip2
  1012.     AND    BL,0FH
  1013.     OR    BL,AL
  1014. Go_treskip2:
  1015.     MOV    [TREMOLOCMD+SI],BL
  1016. Go_Tremolo2:
  1017.     MOV    AL,[TREMOLOPOS+SI]
  1018.     SHR    AL,2
  1019.     AND    AX,1FH
  1020.     MOV    BL,[WAVECONTROL+SI]
  1021.     SHR    BL,4
  1022.     AND    BL,3
  1023.     JZ    SHORT Go_tre_sine
  1024.     SHL    AL,3
  1025.     CMP    BL,1
  1026.     JE    SHORT Go_tre_rampdown
  1027.     MOV    BL,255
  1028.     JMP    SHORT Go_tre_set
  1029. Go_tre_rampdown:
  1030.     CMP    [TREMOLOPOS+SI],0
  1031.     JG    SHORT Go_tre_rampdown2
  1032.     MOV    BL,AL
  1033.     NOT    BL
  1034.     JMP    SHORT Go_tre_set
  1035. Go_tre_rampdown2:
  1036.     MOV    BL,AL
  1037.     JMP    SHORT Go_tre_set
  1038. Go_tre_sine:
  1039.     MOVZX    BX,AL
  1040.     MOV    BL,[MT_VIBRATOTABLE+BX]
  1041. Go_tre_set:
  1042.     MOV    AL,[TREMOLOCMD+SI]
  1043.     AND    AL,0FH
  1044.     MUL    BL
  1045.     MOV    BX,AX
  1046.     SHR    BX,6
  1047.     MOV    AL,[VOLUME+SI]
  1048.     CMP    [TREMOLOPOS+SI],0
  1049.     JG    SHORT Go_TremoloNeg        ; BMI  jns
  1050.     ADD    AL,BL
  1051.     JMP    SHORT Go_Tremolo3
  1052. Go_TremoloNeg:
  1053.     SUB    AL,BL
  1054. Go_Tremolo3:
  1055.     JNC    SHORT Go_TremoloSkip
  1056.     XOR    AX,AX
  1057. Go_TremoloSkip:
  1058.     CMP    AL,40H
  1059.     JBE    SHORT Go_TremoloOK        ; BLS
  1060.     MOV    AL,40H
  1061. Go_TremoloOK:
  1062.     MOV    [MVOL+SI],AL            ;was ah
  1063.     MOV    AL,[TREMOLOCMD+SI]
  1064.     AND    AL,0F0H
  1065.     SHR    AL,2
  1066.     ADD    [TREMOLOPOS+SI],AL
  1067.     RET
  1068. Go_Tremolo ENDP
  1069. ;────────────────────────────────────────────────────────────────────────────
  1070. ; Effect 9 -- Sample Offset
  1071. ;────────────────────────────────────────────────────────────────────────────
  1072. Go_SampleOffset PROC NEAR
  1073.     MOVZX    AX,[CMDLO+SI]
  1074.     OR    AL,AL
  1075.     JZ    SHORT Go_sononew
  1076.     MOV    [SAMPLEOFFSET+SI],AL
  1077. Go_sononew:
  1078.     MOVZX    AX,[SAMPLEOFFSET+SI]
  1079.     XCHG    AL,AH
  1080.     CMP    AX,[MMAXREP+DI]
  1081.     JAE    SHORT Go_sofskip
  1082.     MOV    [MOFS+DI],AX
  1083.     RET
  1084. Go_sofskip:
  1085.     MOV    AX,[MOFS+DI]
  1086.     MOV    [MMAXREP+DI],AX
  1087.     RET
  1088. Go_SampleOffset ENDP
  1089. ;────────────────────────────────────────────────────────────────────────────
  1090. ; Effect A -- Volume Slide
  1091. ;────────────────────────────────────────────────────────────────────────────
  1092. Go_VolumeSlide PROC NEAR
  1093.     MOV    AL,[CMDLO+SI]
  1094.     SHR    AL,4
  1095.     OR    AL,AL
  1096.     JZ    SHORT Go_VolSlideDown
  1097. Go_VolSlideUp:
  1098.     ADD    [VOLUME+SI],AL
  1099.     CMP    [VOLUME+SI],40H
  1100.     JBE    SHORT Go_vsdskip
  1101.     MOV    [VOLUME+SI],40H
  1102.     JMP    SHORT Go_vsdskip
  1103. Go_VolSlideDown:
  1104.     MOV    AL,[CMDLO+SI]
  1105.     AND    AL,0FH
  1106. Go_VolSlideDown2:
  1107.     SUB    [VOLUME+SI],AL
  1108.     JNC    SHORT Go_vsdskip
  1109.     MOV    [VOLUME+SI],0
  1110. Go_vsdskip:
  1111.     MOV    AL,[VOLUME+SI]
  1112.     MOV    [MVOL+SI],AL        ;was ah
  1113.     RET
  1114. Go_VolumeSlide ENDP
  1115. ;────────────────────────────────────────────────────────────────────────────
  1116. ; Effect B -- Position Jump
  1117. ;────────────────────────────────────────────────────────────────────────────
  1118. Go_PositionJump PROC NEAR
  1119.     MOV    AL,[CMDLO+SI]        ; Get where to jump
  1120.     DEC    AL            ; Update the
  1121.     MOV    MT_SONGPOS,AL        ; information.
  1122. Go_pj2:    MOV    MT_PBREAKPOS,0
  1123.     MOV    MT_POSJUMPFLAG,1
  1124.     RET
  1125. Go_PositionJump ENDP
  1126. ;────────────────────────────────────────────────────────────────────────────
  1127. ; Effect C -- Volume Change
  1128. ;────────────────────────────────────────────────────────────────────────────
  1129. Go_VolumeChange PROC NEAR
  1130.     MOV    AL,[CMDLO+SI]        ; Get value for volume
  1131.     CMP    AL,40H            ; Is it greater than 40h?
  1132.     JBE    SHORT Go_VolumeOK    ; Nope
  1133.     MOV    AL,40H
  1134. Go_VolumeOK:
  1135.     MOV    [VOLUME+SI],AL
  1136.     MOV    [MVOL+SI],AL        ;was ah
  1137.     RET
  1138. Go_VolumeChange ENDP
  1139. ;────────────────────────────────────────────────────────────────────────────
  1140. ; Effect D -- Pattern Break
  1141. ;────────────────────────────────────────────────────────────────────────────
  1142. Go_PatternBreak PROC NEAR
  1143.     MOV    AL,[CMDLO+SI]        ; Break to where?
  1144.     MOV    BL,AL            ; POSITION IS IN DECIMAL
  1145.     SHR    AL,4
  1146.     MOV    CL,10
  1147.     MUL    CL
  1148.     AND    BL,0FH
  1149.     ADD    AL,BL
  1150.     CMP    AL,63
  1151.     JG    Go_pj2
  1152.     MOV    MT_PBREAKPOS,AL
  1153.     MOV    MT_POSJUMPFLAG,1
  1154.     RET
  1155. Go_PatternBreak ENDP
  1156. ;────────────────────────────────────────────────────────────────────────────
  1157. ; Effect F -- Set Speed
  1158. ;────────────────────────────────────────────────────────────────────────────
  1159. Go_SetSpeed PROC NEAR
  1160.     MOV    AL,[CMDLO+SI]        ; Get value for speed
  1161.     OR    AL,AL
  1162.     JZ    Go_Return
  1163.     CMP    AL,32            ; Is it a BPM value ?
  1164.     JAE    SHORT Go_SetBPM
  1165.     MOV    MT_COUNTER,0
  1166.     MOV    MT_SPEED,AL
  1167.     RET
  1168. Go_SetBPM:
  1169.     XOR    AH,AH
  1170.     MOV    BPM_VALUE,AX
  1171.     CMP    AL,76            ; MIXROUTINE CANT HANDLE LESS THAN 76
  1172.     JAE    SHORT Go_CheckBPM1
  1173.     MOV    AL,76
  1174. Go_CheckBPM1:
  1175.     CMP    AL,202            ; MIXROUTINE CANT HANDLE MORE THAN 202
  1176.     JBE    SHORT Go_CheckBPM2
  1177.     MOV    AL,202
  1178. Go_CheckBPM2:
  1179.     SHL    AX,1
  1180.     MOV    BL,5            ; Denna bit är för att ställa
  1181.     DIV    BL            ; EFFECTs till annat än 50Hz
  1182.     MOV    DL,AL            ; Detta ger automatiskt en annan
  1183.     XOR    DH,DH            ; PATT_SPEED.; Hz=2*BPM/5
  1184.     XOR    AX,AX
  1185.     MOV    BX,BPM_RATE
  1186.     DIV    BX
  1187.     MOV    WORD PTR BPM_SPEED,AX
  1188.     XOR    AX,AX
  1189.     DIV    BX
  1190.     MOV    WORD PTR BPM_SPEED+2,AX
  1191.     RET
  1192. Go_SetSpeed ENDP
  1193. ;=============================================================================
  1194. Go_CheckMoreEfx PROC NEAR
  1195.     MOVZX    BX,[CMD+SI]
  1196.     SHL    BL,1
  1197.     JMP    [Effect_Jump_Table2+BX]
  1198. Go_CheckMoreEfx ENDP
  1199. ;─────────────────────────────────────────────────────────────────────────────
  1200. ; Effect E
  1201. ;─────────────────────────────────────────────────────────────────────────────
  1202. Go_E_Commands PROC NEAR
  1203.     MOVZX    BX,[CMDLO+SI]
  1204.     SHR    BL,4
  1205.     SHL    BL,1
  1206.     MOV    AL,[CMDLO+SI]
  1207.     AND    AL,0FH
  1208.     JMP    [Effect_Jump_Table3+BX]
  1209. ;-----------------------------------------------------------------------------
  1210. ; Effect 0 -- FilterOnOff
  1211. ; Effect 1 -- Fine Porta Up
  1212. ;-----------------------------------------------------------------------------
  1213. Go_FinePortaUp:
  1214.     CMP    MT_COUNTER,0
  1215.     JNE    Go_Return
  1216.     MOV    MT_LOWMASK,0FH
  1217.     JMP    Go_PortaUp
  1218. ;-----------------------------------------------------------------------------
  1219. ; Effect 2 -- Fine Porta Down
  1220. ;-----------------------------------------------------------------------------
  1221. Go_FinePortaDown:
  1222.     CMP    MT_COUNTER,0
  1223.     JNE    Go_Return
  1224.     MOV    MT_LOWMASK,0FH
  1225.     JMP    Go_PortaDown
  1226. ;-----------------------------------------------------------------------------
  1227. ; Effect 3 -- Set Gliss Control
  1228. ;-----------------------------------------------------------------------------
  1229. Go_SetGlissControl:
  1230.     AND    [GLISSFUNK+SI],0F0H
  1231.     OR    [GLISSFUNK+SI],AL
  1232.     RET
  1233. ;-----------------------------------------------------------------------------
  1234. ; Effect 4 -- Set Vibrato Control
  1235. ;-----------------------------------------------------------------------------
  1236. Go_SetVibratoControl:
  1237.     AND    [WAVECONTROL+SI],0F0H
  1238.     OR    [WAVECONTROL+SI],AL
  1239.     RET
  1240. ;-----------------------------------------------------------------------------
  1241. ; Effect 5 -- Set Fine Tune
  1242. ;-----------------------------------------------------------------------------
  1243. Go_SetFineTune:
  1244.     MOV    [FINETUNE+SI],AL
  1245.     RET
  1246. ;-----------------------------------------------------------------------------
  1247. ; Effect 6 -- Jump Loop
  1248. ;-----------------------------------------------------------------------------
  1249. Go_JumpLoop:
  1250.     CMP    MT_COUNTER,0
  1251.     JNE    Go_Return
  1252.     OR    AL,AL
  1253.     JZ    SHORT Go_SetLoop
  1254.     CMP    [LOOPCOUNT+SI],0
  1255.     JE    SHORT Go_jumpcnt
  1256.     DEC    [LOOPCOUNT+SI]
  1257.     JZ    Go_Return
  1258. Go_jmploop:
  1259.     MOV    AL,[PATTPOS+SI]
  1260.     MOV    MT_PBREAKPOS,AL
  1261.     MOV    MT_PBREAKFLAG,1
  1262.     RET
  1263. Go_jumpcnt:
  1264.     MOV    [LOOPCOUNT+SI],AL
  1265.     JMP    Go_jmploop
  1266. Go_SetLoop:
  1267.     MOV    AX,MT_PATTERNPOS
  1268.     SHR    AX,2
  1269.     MOV    [PATTPOS+SI],AL
  1270.     RET
  1271. ;-----------------------------------------------------------------------------
  1272. ; Effect 7 -- Set Tremolo Control
  1273. ;-----------------------------------------------------------------------------
  1274. Go_SetTremoloControl:
  1275.     SHL    AL,4
  1276.     AND    [WAVECONTROL+SI],0FH
  1277.     OR    [WAVECONTROL+SI],AL
  1278.     RET
  1279. ;-----------------------------------------------------------------------------
  1280. ; Effect 9 -- Retrig Note
  1281. ;-----------------------------------------------------------------------------
  1282. Go_RetrigNote:
  1283.     MOV    BL,AL
  1284.     OR    BL,BL
  1285.     JZ    SHORT Go_rtnend
  1286.     MOVZX    AX,MT_COUNTER
  1287.     OR    AL,AL
  1288.     JNZ    SHORT Go_rtnskp
  1289.     CMP    [NOTE+DI],0
  1290.     JNE    SHORT Go_rtnskp
  1291.     MOV    MT_COUNTER,0
  1292. Go_rtnskp:
  1293.     DIV    BL
  1294.     XCHG    AL,AH
  1295.     OR    AL,AL
  1296.     JNZ    SHORT Go_rtnend
  1297. Go_DoRetrig:
  1298.     XOR    AX,AX
  1299.     MOV    [MOFS+DI],AX
  1300.     MOV    [MOFLOW+SI],AL
  1301.     MOV    AX,[LENGTHI+DI]
  1302.     MOV    [MMAXREP+DI],AX
  1303.     MOV    AX,[LOOPSTART+DI]
  1304.     MOV    [MREPEAT+DI],AX
  1305.     ADD    AX,[REPLEN+DI]
  1306.     MOV    [MREPLEN+DI],AX
  1307. Go_rtnend:
  1308.     RET
  1309. ;-----------------------------------------------------------------------------
  1310. ; Effect A -- Volume Fine Up
  1311. ;-----------------------------------------------------------------------------
  1312. Go_VolumeFineUp:
  1313.     CMP    MT_COUNTER,0
  1314.     JNE    Go_Return
  1315.     JMP    Go_VolSlideUp
  1316. ;-----------------------------------------------------------------------------
  1317. ; Effect B -- Volume Fine Down
  1318. ;-----------------------------------------------------------------------------
  1319. Go_VolumeFineDown:
  1320.     CMP    MT_COUNTER,0
  1321.     JNZ    Go_Return
  1322.     JMP    Go_VolSlideDown2
  1323. ;-----------------------------------------------------------------------------
  1324. ; Effect C -- Note Cut
  1325. ;-----------------------------------------------------------------------------
  1326. Go_NoteCut:
  1327.     CMP    AL,MT_COUNTER
  1328.     JNE    Go_Return
  1329.     MOV    [VOLUME+SI],0
  1330.     MOV    [MVOL+SI],AL
  1331.     RET
  1332. ;-----------------------------------------------------------------------------
  1333. ; Effect D -- Note Delay
  1334. ;-----------------------------------------------------------------------------
  1335. Go_NoteDelay:
  1336.     CMP    AL,MT_COUNTER
  1337.     JNE    Go_Return
  1338.     CMP    [NOTE+DI],0
  1339.     JE    Go_Return
  1340.     JMP    Go_DoRetrig
  1341. ;-----------------------------------------------------------------------------
  1342. ; Effect E -- Pattern Delay
  1343. ;-----------------------------------------------------------------------------
  1344. Go_PatternDelay:
  1345.     CMP    MT_COUNTER,0
  1346.     JNE    Go_Return
  1347.     CMP    MT_PATTDELAYTIME2,0
  1348.     JNZ    Go_Return
  1349.     INC    AL
  1350.     MOV    MT_PATTDELAYTIME,AL
  1351.     RET
  1352. ;-----------------------------------------------------------------------------
  1353. ; Effect F -- Funk It
  1354. ;-----------------------------------------------------------------------------
  1355. Go_E_Commands ENDP
  1356. ;=============================================================================
  1357.  
  1358.  
  1359. ;=============================================================================
  1360. MIXUP_CHANNELS PROC NEAR
  1361.     CMP    MOD_STAT,3        ;MOD HAS FINISHED
  1362.     JB    SHORT GMX7
  1363.     XOR    AX,AX
  1364.     XOR    BX,BX
  1365.     MOV    CX,MAX_CHAN_NUMB
  1366. LMX4:    MOV    [MSEG+BX],AX
  1367.     INC    BX
  1368.     INC    BX
  1369.     LOOP    LMX4
  1370. GMX7:    MOV    CX,DMA_CX
  1371.     CMP    MOD_STAT,2
  1372.     JB    SHORT GMX3
  1373.     OUT    0CH,AL            ;DMA FLIP-FLOP RESET
  1374.     MOVZX    DX,DMA_CHANNEL
  1375.     SHL    DL,1
  1376.     IN    AL,DX            ;GET DMA POSITION
  1377.     XCHG    AL,AH
  1378.     IN    AL,DX
  1379.     XCHG    AL,AH
  1380.     SUB    AX,DMA_POFF        ;AX IS OFFSET OF DMA-POS
  1381.     AND    AX,0FFFEH
  1382.     ADD    AX,DMA_MORE
  1383.     CMP    AX,DMA_MAX
  1384.     JB    SHORT GMX1
  1385.     SUB    AX,DMA_MAX
  1386. GMX1:    ADD    AX,DMA_OFFSET
  1387.     SUB    AX,DMA_PTR
  1388.     JNC    SHORT GMX2
  1389.     ADD    AX,DMA_MAX
  1390. GMX2:    MOV    CX,AX            ;CX IS NUMBER OF BYTES TO CALCULATE
  1391.     ADD    AX,DMA_PTR
  1392.     SUB    AX,DMA_OFFSET
  1393.     SUB    AX,2000H
  1394.     JC    SHORT GMX3
  1395.     SUB    CX,AX
  1396. GMX3:    XOR    BX,BX
  1397.     XOR    DI,DI
  1398.     CLD
  1399.     SHR    CX,1
  1400.     JZ    SHORT GMX5
  1401.     TEST    SBPRO_FLAG,1
  1402.     JNZ    SHORT SBPRO_MIXING    ;SB MONO-MIXING
  1403.     CALL    MIX_CHANNELA        ;INIT BUFFER WITH FIRST CHANNEL
  1404.     INC    BX
  1405.     INC    DI
  1406.     INC    DI
  1407.     DEC    CH_NUMB
  1408. LMX1:    CALL    MIX_CHANNELM        ;MIX CHANNELS
  1409.     INC    BX
  1410.     INC    DI
  1411.     INC    DI
  1412.     CMP    BX,CH_NUMB
  1413.     JB    LMX1
  1414.     INC    CH_NUMB
  1415.     CALL    MIX_CHANNELX        ;END UP BUFFER WITH LAST CHANNEL
  1416.     MOV    AX,SAM_SEG1
  1417.     OR    AX,SAM_SEG2
  1418.     JZ    SHORT LMX2
  1419.     CALL    MIX_CHANNELS1        ;SAMPLE1: MIDDLE CHANNEL
  1420.     CALL    MIX_CHANNELS2        ;SAMPLE2: MIDDLE CHANNEL
  1421.     CALL    FIXUP_CHANNELS1        ;END UP CHANNEL BY CONVERTING IT TO PC
  1422. LMX2:    MOV    AX,DMA_NEWPTR        ;CHECK DMA-BUFFER OVERFLOW
  1423.     MOV    SI,DMA_MAX        ;ITS A RING BUFFER
  1424.     ADD    SI,DMA_OFFSET
  1425.     CMP    AX,SI
  1426.     JB    SHORT GMX4
  1427.     MOV    CX,AX
  1428.     MOV    DI,DMA_OFFSET
  1429.     SUB    CX,SI
  1430.     JZ    SHORT GMX6
  1431.     CLD
  1432.     SHR    CX,1
  1433.     PUSH    DS
  1434.     MOV    ES,DMA_SEG
  1435.     MOV    DS,DMA_SEG
  1436.     REP MOVSW            ;MOVE OVERFLOW DATA
  1437.     POP    DS
  1438. GMX6:    MOV    AX,DI
  1439. GMX4:    MOV    DMA_PTR,AX        ;START DSP OUTPUT
  1440.     CMP    MOD_STAT,1
  1441.     JNE    SHORT GMX5
  1442.     INC    MOD_STAT
  1443.     CALL    DSP_OUT
  1444. GMX5:    RET
  1445. SBPRO_MIXING:
  1446.     SHR    CX,1            ;SBPRO STEREO-MIXING
  1447.     JZ    GMX5
  1448.     MOV    AX,[STEREO_PANNING+DI]
  1449.     ADD    DMA_PTR,AX
  1450.     CALL    MIX_CHANNELA        ;INIT BUFFER WITH FIRST CHANNEL
  1451.     INC    BX
  1452.     INC    DI
  1453.     INC    DI
  1454.     PUSH    DMA_NEWPTR
  1455.     MOV    AX,[STEREO_PANNING+DI]
  1456.     ADD    DMA_PTR,AX
  1457.     CALL    MIX_CHANNELA        ;THIS CHANNEL SHOULD BE ON RIGHT
  1458.     INC    BX            ;(OTHERWISE DMA_NEWPTR IS 2 TOO HIGH)
  1459.     INC    DI
  1460.     INC    DI
  1461.     POP    AX
  1462.     CMP    AX,DMA_NEWPTR
  1463.     JAE    SHORT LMX3
  1464.     MOV    DMA_NEWPTR,AX
  1465. LMX3:    MOV    AX,[STEREO_PANNING+DI]
  1466.     ADD    DMA_PTR,AX
  1467.     CALL    MIX_CHANNELM        ;MIX CHANNELS
  1468.     INC    BX
  1469.     INC    DI
  1470.     INC    DI
  1471.     CMP    BX,CH_NUMB
  1472.     JB    LMX3
  1473.     MOV    AX,[STEREO_PANNING+DI]
  1474.     ADD    DMA_PTR,AX
  1475.     CALL    MIX_CHANNELS1        ;SAMPLE1: LEFT CHANNEL
  1476.     CALL    MIX_CHANNELS2        ;SAMPLE2: LEFT CHANNEL
  1477.     ADD    DMA_PTR,2
  1478.     CALL    MIX_CHANNELS3        ;SAMPLE3: RIGHT CHANNEL
  1479.     CALL    MIX_CHANNELS4        ;SAMPLE4: RIGHT CHANNEL
  1480.     SUB    DMA_PTR,2
  1481.     CALL    FIXUP_CHANNELS2        ;END UP CHANNEL BY CONVERTING IT TO PC
  1482.     JMP    LMX2
  1483. MIXUP_CHANNELS ENDP
  1484. ;-----------------------------------------------------------------------------
  1485. MIX_CHANNELA PROC NEAR
  1486.     PUSH    CX BX DI
  1487.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1488.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1489.     MOV    BYTE PTR SLA2+2,DL
  1490.     MOV    BYTE PTR SLA3+2,DH
  1491.     MOV    BYTE PTR SLA5+2,DL
  1492.     MOV    BYTE PTR SLA6+2,DH
  1493.     MOV    WORD PTR SLA1,01472H    ;JB SHORT +20
  1494.     MOV    WORD PTR SLA4,01472H    ;JB SHORT +20
  1495.     OR    DH,DH
  1496.     JNZ    SHORT MIX_NOIPA
  1497.     MOV    WORD PTR SLA1,0D68AH    ;MOV DL,DH
  1498.     MOV    WORD PTR SLA4,0D68AH    ;MOV DL,DH
  1499. MIX_NOIPA:
  1500.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1501.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1502.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1503.     MUL    BL
  1504.     XOR    AL,AL
  1505.     ADD    AX,MIXMUL_OFFSET
  1506.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1507.     MOV    ES,[MSEG+DI]
  1508.     MOV    AX,[MMAXREP+DI]        ;SP IS OFFSET OF SAMPLE ENDING
  1509.     DEC    AX
  1510.     MOV    WORD PTR SELFM1+2,AX
  1511.     MOV    WORD PTR SELFM2+2,AX
  1512.     JMP    SHORT CLEAR_PREF1    ;CLEAR PREFETCH QUEUE!!!
  1513. CLEAR_PREF1:
  1514.     MOV    DI,DMA_PTR
  1515.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1516.     MOV    AX,ES            ;ES:SI IS SAMPLE-DATA POINTER
  1517.     OR    AX,AX
  1518.     JZ    SILENT_FILLA
  1519. MIX_LOOPA:
  1520. SELFM1:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1521.     JAE    SHORT REST_FILLA
  1522.     MOV    AX,ES:[SI]
  1523. SLA1:    MOV    DL,DH            ;SMCODE
  1524.     MOVSX    BP,AL
  1525.     SAR    AH,1
  1526.     SAR    AL,1
  1527.     SHR    DL,1
  1528.     SUB    AL,AH
  1529.     NEG    AL
  1530.     IMUL    DL
  1531.     SAR    AX,6
  1532.     ADD    AX,BP
  1533.     XLATB
  1534. SLA2:    ADD    DH,0            ;SMCODE
  1535. SLA3:    ADC    SI,0            ;SMCODE
  1536.     MOV    [DI],AL
  1537. SELFM2:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1538.     JAE    SHORT REST_FILLA
  1539.     MOV    AX,ES:[SI]
  1540. SLA4:    MOV    DL,DH            ;SMCODE
  1541.     MOVSX    BP,AL
  1542.     SAR    AH,1
  1543.     SAR    AL,1
  1544.     SHR    DL,1
  1545.     SUB    AL,AH
  1546.     NEG    AL
  1547.     IMUL    DL
  1548.     SAR    AX,6
  1549.     ADD    AX,BP
  1550.     XLATB
  1551. SLA5:    ADD    DH,0            ;SMCODE
  1552. SLA6:    ADC    SI,0            ;SMCODE
  1553.     MOV    [DI+1],AL
  1554. SELFN1:    ADD    DI,2            ;SELFMODIFYING CODE
  1555.     LOOP    MIX_LOOPA
  1556. MIX_ENDA:
  1557.     MOV    AX,CS
  1558.     MOV    DS,AX
  1559.     MOV    AX,ES
  1560.     MOV    DMA_NEWPTR,DI
  1561.     POP    DI BX CX
  1562.     MOV    [MSEG+DI],AX
  1563.     MOV    [MOFLOW+BX],DH
  1564.     MOV    [MOFS+DI],SI
  1565.     RET
  1566. REST_FILLA:
  1567.     POP    SI
  1568.     PUSH    SI
  1569.     MOV    AX,CS:[MREPLEN+SI]
  1570.     OR    AX,AX
  1571.     JZ    SHORT SILENT_FILLA
  1572.     MOV    CS:[MMAXREP+SI],AX
  1573.     DEC    AX
  1574.     MOV    WORD PTR CS:SELFM1+2,AX
  1575.     MOV    WORD PTR CS:SELFM2+2,AX
  1576.     MOV    SI,CS:[MREPEAT+SI]
  1577.     JMP    MIX_LOOPA
  1578. SILENT_FILLA:
  1579.     MOV    BX,DS
  1580.     MOV    ES,BX
  1581.     TEST    CS:SBPRO_FLAG,1
  1582.     JNZ    SHORT SILENT_FILLB
  1583.     REP STOSW
  1584.     MOV    ES,AX
  1585.     JMP    MIX_ENDA
  1586. SILENT_FILLB:
  1587.     STOSW
  1588.     INC    DI
  1589.     INC    DI
  1590.     LOOP    SILENT_FILLB
  1591.     MOV    ES,AX
  1592.     JMP    MIX_ENDA
  1593. MIX_CHANNELA ENDP
  1594. ;-----------------------------------------------------------------------------
  1595. MIX_CHANNELM PROC NEAR
  1596.     PUSH    CX BX DI
  1597.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1598.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1599.     MOV    BYTE PTR SLM2+2,DL
  1600.     MOV    BYTE PTR SLM3+2,DH
  1601.     MOV    BYTE PTR SLM5+2,DL
  1602.     MOV    BYTE PTR SLM6+2,DH
  1603.     MOV    WORD PTR SLM1,01472H    ;JB SHORT +20
  1604.     MOV    WORD PTR SLM4,01472H    ;JB SHORT +20
  1605.     OR    DH,DH
  1606.     JNZ    SHORT MIX_NOIPM
  1607.     MOV    WORD PTR SLM1,0D68AH    ;MOV DL,DH
  1608.     MOV    WORD PTR SLM4,0D68AH    ;MOV DL,DH
  1609. MIX_NOIPM:
  1610.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1611.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1612.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1613.     MUL    BL
  1614.     XOR    AL,AL
  1615.     ADD    AX,MIXMUL_OFFSET
  1616.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1617.     MOV    ES,[MSEG+DI]
  1618.     MOV    AX,[MMAXREP+DI]        ;OFFSET OF SAMPLE ENDING
  1619.     DEC    AX
  1620.     MOV    WORD PTR SELFM3+2,AX
  1621.     MOV    WORD PTR SELFM4+2,AX
  1622.     JMP    SHORT CLEAR_PREF2    ;CLEAR PREFETCH QUEUE!!!
  1623. CLEAR_PREF2:
  1624.     MOV    DI,DMA_PTR
  1625.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1626.     MOV    AX,ES
  1627.     OR    AX,AX
  1628.     JZ    SHORT MIX_ENDM
  1629. MIX_LOOPM:
  1630. SELFM3:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1631.     JAE    SHORT REST_FILLM
  1632.     MOV    AX,ES:[SI]
  1633. SLM1:    MOV    DL,DH            ;SMCODE
  1634.     MOVSX    BP,AL
  1635.     SAR    AH,1
  1636.     SAR    AL,1
  1637.     SHR    DL,1
  1638.     SUB    AL,AH
  1639.     NEG    AL
  1640.     IMUL    DL
  1641.     SAR    AX,6
  1642.     ADD    AX,BP
  1643.     XLATB
  1644. SLM2:    ADD    DH,0            ;SMCODE
  1645. SLM3:    ADC    SI,0            ;SMCODE
  1646.     ADD    [DI],AL
  1647.     JNO    SHORT SELFM4
  1648.     SHR    AL,7
  1649.     ADD    AL,7FH
  1650.     MOV    [DI],AL
  1651. SELFM4:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1652.     JAE    SHORT REST_FILLM
  1653.     MOV    AX,ES:[SI]
  1654. SLM4:    MOV    DL,DH            ;SMCODE
  1655.     MOVSX    BP,AL
  1656.     SAR    AH,1
  1657.     SAR    AL,1
  1658.     SHR    DL,1
  1659.     SUB    AL,AH
  1660.     NEG    AL
  1661.     IMUL    DL
  1662.     SAR    AX,6
  1663.     ADD    AX,BP
  1664.     XLATB
  1665. SLM5:    ADD    DH,0            ;SMCODE
  1666. SLM6:    ADC    SI,0            ;SMCODE
  1667.     ADD    [DI+1],AL
  1668.     JNO    SHORT SELFN2
  1669.     SHR    AL,7
  1670.     ADD    AL,7FH
  1671.     MOV    [DI+1],AL
  1672. SELFN2:    ADD    DI,2            ;SELFMODIFYING CODE
  1673.     LOOP    MIX_LOOPM
  1674. MIX_ENDM:
  1675.     MOV    AX,CS
  1676.     MOV    DS,AX
  1677.     MOV    AX,ES
  1678.     POP    DI BX CX
  1679.     MOV    [MSEG+DI],AX
  1680.     MOV    [MOFLOW+BX],DH
  1681.     MOV    [MOFS+DI],SI
  1682.     RET
  1683. REST_FILLM:
  1684.     POP    SI
  1685.     PUSH    SI
  1686.     MOV    AX,CS:[MREPLEN+SI]
  1687.     OR    AX,AX
  1688.     JZ    SHORT SILENT_FILLM
  1689.     MOV    CS:[MMAXREP+SI],AX
  1690.     DEC    AX
  1691.     MOV    WORD PTR CS:SELFM3+2,AX
  1692.     MOV    WORD PTR CS:SELFM4+2,AX
  1693.     MOV    SI,CS:[MREPEAT+SI]
  1694.     JMP    MIX_LOOPM
  1695. SILENT_FILLM:
  1696.     MOV    ES,AX
  1697.     JMP    MIX_ENDM
  1698. MIX_CHANNELM ENDP
  1699. ;-----------------------------------------------------------------------------
  1700. MIX_CHANNELX PROC NEAR
  1701.     PUSH    CX BX DI
  1702.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1703.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1704.     MOV    BYTE PTR SLX2+2,DL
  1705.     MOV    BYTE PTR SLX3+2,DH
  1706.     MOV    BYTE PTR SLX5+2,DL
  1707.     MOV    BYTE PTR SLX6+2,DH
  1708.     MOV    WORD PTR SLX1,01472H    ;JB SHORT +20
  1709.     MOV    WORD PTR SLX4,01472H    ;JB SHORT +20
  1710.     OR    DH,DH
  1711.     JNZ    SHORT MIX_NOIPX
  1712.     MOV    WORD PTR SLX1,0D68AH    ;MOV DL,DH
  1713.     MOV    WORD PTR SLX4,0D68AH    ;MOV DL,DH
  1714. MIX_NOIPX:
  1715.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1716.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1717.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1718.     MUL    BL
  1719.     XOR    AL,AL
  1720.     ADD    AX,MIXMUL_OFFSET
  1721.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1722.     MOV    ES,[MSEG+DI]
  1723.     MOV    AX,[MMAXREP+DI]        ;SP IS OFFSET OF SAMPLE ENDING
  1724.     DEC    AX
  1725.     MOV    WORD PTR SELFM5+2,AX
  1726.     MOV    WORD PTR SELFM6+2,AX
  1727.     MOV    WORD PTR SELFM7+2,0
  1728.     MOV    AX,SAM_SEG1
  1729.     OR    AX,SAM_SEG2
  1730.     JNZ    SHORT YES_SAMPLES
  1731.     MOV    WORD PTR SELFM7+2,8080H
  1732. YES_SAMPLES:
  1733.     JMP    SHORT CLEAR_PREF3    ;CLEAR PREFETCH QUEUE!!!
  1734. CLEAR_PREF3:
  1735.     MOV    DI,DMA_PTR
  1736.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1737.     MOV    AX,ES            ;ES:SI IS SAMPLE-DATA POINTER
  1738.     OR    AX,AX
  1739.     JZ    SILENT_FILLX
  1740. MIX_LOOPX:
  1741. SELFM5:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1742.     JAE    SHORT REST_FILLX
  1743.     MOV    AX,ES:[SI]
  1744. SLX1:    MOV    DL,DH            ;SMCODE
  1745.     MOVSX    BP,AL
  1746.     SAR    AH,1
  1747.     SAR    AL,1
  1748.     SHR    DL,1
  1749.     SUB    AL,AH
  1750.     NEG    AL
  1751.     IMUL    DL
  1752.     SAR    AX,6
  1753.     ADD    AX,BP
  1754.     XLATB
  1755. SLX2:    ADD    DH,0            ;SMCODE
  1756. SLX3:    ADC    SI,0            ;SMCODE
  1757.     ADD    [DI],AL
  1758.     JNO    SHORT SELFM6
  1759.     SHR    AL,7
  1760.     ADD    AL,7FH
  1761.     MOV    [DI],AL
  1762. SELFM6:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1763.     JAE    SHORT REST_FILLX
  1764.     MOV    AX,ES:[SI]
  1765. SLX4:    MOV    DL,DH            ;SMCODE
  1766.     MOVSX    BP,AL
  1767.     SAR    AH,1
  1768.     SAR    AL,1
  1769.     SHR    DL,1
  1770.     SUB    AL,AH
  1771.     NEG    AL
  1772.     IMUL    DL
  1773.     SAR    AX,6
  1774.     ADD    AX,BP
  1775.     XLATB
  1776. SLX5:    ADD    DH,0            ;SMCODE
  1777. SLX6:    ADC    SI,0            ;SMCODE
  1778.     ADD    [DI+1],AL
  1779.     JNO    SHORT SELFM7
  1780.     SHR    AL,7
  1781.     ADD    AL,7FH
  1782.     MOV    [DI+1],AL
  1783. SELFM7:    XOR    WORD PTR [DI],8080H
  1784.     INC    DI
  1785.     INC    DI
  1786.     LOOP    MIX_LOOPX
  1787. MIX_ENDX:
  1788.     MOV    AX,CS
  1789.     MOV    DS,AX
  1790.     MOV    AX,ES
  1791.     POP    DI BX CX
  1792.     MOV    [MSEG+DI],AX
  1793.     MOV    [MOFLOW+BX],DH
  1794.     MOV    [MOFS+DI],SI
  1795.     RET
  1796. REST_FILLX:
  1797.     POP    SI
  1798.     PUSH    SI
  1799.     MOV    AX,CS:[MREPLEN+SI]
  1800.     OR    AX,AX
  1801.     JZ    SHORT SILENT_FILLX
  1802.     MOV    CS:[MMAXREP+SI],AX
  1803.     DEC    AX
  1804.     MOV    WORD PTR CS:SELFM5+2,AX
  1805.     MOV    WORD PTR CS:SELFM6+2,AX
  1806.     MOV    SI,CS:[MREPEAT+SI]
  1807.     JMP    MIX_LOOPX
  1808. SILENT_FILLX:
  1809.     MOV    ES,AX
  1810.     MOV    AX,CS:[SAM_SEG1]
  1811.     OR    AX,CS:[SAM_SEG2]
  1812.     JNZ    MIX_ENDX
  1813. SILENT_FILLL:
  1814.     XOR    WORD PTR [DI],8080H
  1815.     INC    DI
  1816.     INC    DI
  1817.     LOOP    SILENT_FILLL
  1818.     JMP    MIX_ENDX
  1819. MIX_CHANNELX ENDP
  1820. ;-----------------------------------------------------------------------------
  1821. FIXUP_CHANNELS1 PROC NEAR
  1822.     MOV    DI,DMA_PTR
  1823.     MOV    DS,DMA_SEG
  1824.     SHR    CX,1
  1825.     JNC    SHORT FIXUP_LOOP1
  1826.     XOR    WORD PTR [DI],8080H
  1827.     INC    DI
  1828.     INC    DI
  1829. FIXUP_LOOP1:
  1830.     XOR    DWORD PTR [DI],80808080H
  1831.     ADD    DI,4
  1832.     LOOP    FIXUP_LOOP1
  1833.     MOV    AX,CS
  1834.     MOV    DS,AX
  1835.     RET
  1836. FIXUP_CHANNELS1 ENDP
  1837. ;-----------------------------------------------------------------------------
  1838. FIXUP_CHANNELS2 PROC NEAR
  1839.     MOV    DI,DMA_PTR
  1840.     MOV    DS,DMA_SEG
  1841. FIXUP_LOOP2:
  1842.     XOR    DWORD PTR [DI],80808080H
  1843.     INC    DI
  1844.     ROL    WORD PTR [DI],8
  1845.     ADD    DI,3
  1846.     LOOP    FIXUP_LOOP2
  1847.     MOV    AX,CS
  1848.     MOV    DS,AX
  1849.     RET
  1850. FIXUP_CHANNELS2 ENDP
  1851. ;-----------------------------------------------------------------------------
  1852. MIX_CHANNELS1 PROC NEAR
  1853.     CMP    SAM_SEG1,0
  1854.     JE    GO_BACKS1
  1855.     CALL    EMS_SAVE
  1856.     PUSH    EAX
  1857.     MOV    EAX,SAM_OFS1
  1858.     CALL    EMS_PAGING
  1859.     POP    EAX
  1860.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1861.     MOV    DX,SAM_FRQ1        ;OFF ADD AFTER FIXED POINT (X/256)
  1862.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1863.     MOV    DH,SAM_OFL1        ;ACTUAL AFTER FIXED POINT VALUE
  1864.     MOV    BX,SAM_MAX1        ;COUNTER FOR SAMPLE ENDING
  1865.     MOV    DI,DMA_PTR
  1866.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1867.     PUSH    CX SI
  1868. MIX_LOOPS1:
  1869.     MOV    AL,ES:[SI]
  1870.     ADD    DH,DL
  1871.     ADC    SI,BP
  1872.     SUB    DH,DL
  1873.     ADD    DH,DL
  1874.     SBB    BX,BP
  1875.     JC    SHORT MIX_ENDS1
  1876.     JZ    SHORT MIX_ENDS1
  1877.     MOV    AH,ES:[SI]
  1878.     ADD    DH,DL
  1879.     ADC    SI,BP
  1880.     ADD    [DI],AL
  1881.     JNO    SHORT MIX_OS11
  1882.     SHR    AL,7
  1883.     ADD    AL,7FH
  1884.     MOV    [DI],AL
  1885. MIX_OS11:
  1886.     ADD    [DI+1],AH
  1887.     JNO    SHORT SELFN3
  1888.     SHR    AH,7
  1889.     ADD    AH,7FH
  1890.     MOV    [DI+1],AH
  1891. SELFN3:    ADD    DI,2
  1892.     SUB    DH,DL
  1893.     ADD    DH,DL
  1894.     SBB    BX,BP
  1895.     JC    SHORT MIX_ENDS1
  1896.     JZ    SHORT MIX_ENDS1
  1897.     LOOP    MIX_LOOPS1
  1898. MIX_REST1:
  1899.     MOV    AX,CS
  1900.     MOV    DS,AX
  1901.     MOV    SAM_OFL1,DH
  1902.     POP    AX CX
  1903.     SUB    SI,AX
  1904.     PUSH    EAX
  1905.     MOVZX    EAX,SI
  1906.     ADD    SAM_OFS1,EAX
  1907.     POP    EAX
  1908.     MOV    SAM_MAX1,BX
  1909.     CALL    EMS_RESTORE
  1910. GO_BACKS1:
  1911.     RET
  1912. MIX_ENDS1:
  1913.     MOV    CS:SAM_SEG1,0
  1914.     JMP    MIX_REST1
  1915. MIX_CHANNELS1 ENDP
  1916. ;-----------------------------------------------------------------------------
  1917. MIX_CHANNELS2 PROC NEAR
  1918.     CMP    SAM_SEG2,0
  1919.     JE    GO_BACKS2
  1920.     CALL    EMS_SAVE
  1921.     PUSH    EAX
  1922.     MOV    EAX,SAM_OFS2
  1923.     CALL    EMS_PAGING
  1924.     POP    EAX
  1925.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1926.     MOV    DX,SAM_FRQ2        ;OFF ADD AFTER FIXED POINT (X/256)
  1927.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1928.     MOV    DH,SAM_OFL2        ;ACTUAL AFTER FIXED POINT VALUE
  1929.     MOV    BX,SAM_MAX2        ;COUNTER FOR SAMPLE ENDING
  1930.     MOV    DI,DMA_PTR
  1931.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1932.     PUSH    CX SI
  1933. MIX_LOOPS2:
  1934.     MOV    AL,ES:[SI]
  1935.     ADD    DH,DL
  1936.     ADC    SI,BP
  1937.     SUB    DH,DL
  1938.     ADD    DH,DL
  1939.     SBB    BX,BP
  1940.     JC    SHORT MIX_ENDS2
  1941.     JZ    SHORT MIX_ENDS2
  1942.     MOV    AH,ES:[SI]
  1943.     ADD    DH,DL
  1944.     ADC    SI,BP
  1945.     ADD    [DI],AL
  1946.     JNO    SHORT MIX_OS21
  1947.     SHR    AL,7
  1948.     ADD    AL,7FH
  1949.     MOV    [DI],AL
  1950. MIX_OS21:
  1951.     ADD    [DI+1],AH
  1952.     JNO    SHORT SELFN4
  1953.     SHR    AH,7
  1954.     ADD    AH,7FH
  1955.     MOV    [DI+1],AH
  1956. SELFN4:    ADD    DI,2
  1957.     SUB    DH,DL
  1958.     ADD    DH,DL
  1959.     SBB    BX,BP
  1960.     JC    SHORT MIX_ENDS2
  1961.     JZ    SHORT MIX_ENDS2
  1962.     LOOP    MIX_LOOPS2
  1963. MIX_REST2:
  1964.     MOV    AX,CS
  1965.     MOV    DS,AX
  1966.     MOV    SAM_OFL2,DH
  1967.     POP    AX CX
  1968.     SUB    SI,AX
  1969.     PUSH    EAX
  1970.     MOVZX    EAX,SI
  1971.     ADD    SAM_OFS2,EAX
  1972.     POP    EAX
  1973.     MOV    SAM_MAX2,BX
  1974.     CALL    EMS_RESTORE
  1975. GO_BACKS2:
  1976.     RET
  1977. MIX_ENDS2:
  1978.     MOV    CS:SAM_SEG2,0
  1979.     JMP    MIX_REST2
  1980. MIX_CHANNELS2 ENDP
  1981. ;-----------------------------------------------------------------------------
  1982. MIX_CHANNELS3 PROC NEAR
  1983.     CMP    SAM_SEG3,0
  1984.     JE    GO_BACKS3
  1985.     CALL    EMS_SAVE
  1986.     PUSH    EAX
  1987.     MOV    EAX,SAM_OFS3
  1988.     CALL    EMS_PAGING
  1989.     POP    EAX
  1990.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1991.     MOV    DX,SAM_FRQ3        ;OFF ADD AFTER FIXED POINT (X/256)
  1992.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1993.     MOV    DH,SAM_OFL3        ;ACTUAL AFTER FIXED POINT VALUE
  1994.     MOV    BX,SAM_MAX3        ;COUNTER FOR SAMPLE ENDING
  1995.     MOV    DI,DMA_PTR
  1996.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1997.     PUSH    CX SI
  1998. MIX_LOOPS3:
  1999.     MOV    AL,ES:[SI]
  2000.     ADD    DH,DL
  2001.     ADC    SI,BP
  2002.     SUB    DH,DL
  2003.     ADD    DH,DL
  2004.     SBB    BX,BP
  2005.     JC    SHORT MIX_ENDS3
  2006.     JZ    SHORT MIX_ENDS3
  2007.     MOV    AH,ES:[SI]
  2008.     ADD    DH,DL
  2009.     ADC    SI,BP
  2010.     ADD    [DI],AL
  2011.     JNO    SHORT MIX_OS31
  2012.     SHR    AL,7
  2013.     ADD    AL,7FH
  2014.     MOV    [DI],AL
  2015. MIX_OS31:
  2016.     ADD    [DI+1],AH
  2017.     JNO    SHORT MIX_OS32
  2018.     SHR    AH,7
  2019.     ADD    AH,7FH
  2020.     MOV    [DI+1],AH
  2021. MIX_OS32:
  2022.     ADD    DI,4
  2023.     SUB    DH,DL
  2024.     ADD    DH,DL
  2025.     SBB    BX,BP
  2026.     JC    SHORT MIX_ENDS3
  2027.     JZ    SHORT MIX_ENDS3
  2028.     LOOP    MIX_LOOPS3
  2029. MIX_REST3:
  2030.     MOV    AX,CS
  2031.     MOV    DS,AX
  2032.     MOV    SAM_OFL3,DH
  2033.     POP    AX CX
  2034.     SUB    SI,AX
  2035.     PUSH    EAX
  2036.     MOVZX    EAX,SI
  2037.     ADD    SAM_OFS3,EAX
  2038.     POP    EAX
  2039.     MOV    SAM_MAX3,BX
  2040.     CALL    EMS_RESTORE
  2041. GO_BACKS3:
  2042.     RET
  2043. MIX_ENDS3:
  2044.     MOV    CS:SAM_SEG3,0
  2045.     JMP    MIX_REST3
  2046. MIX_CHANNELS3 ENDP
  2047. ;-----------------------------------------------------------------------------
  2048. MIX_CHANNELS4 PROC NEAR
  2049.     CMP    SAM_SEG4,0
  2050.     JE    GO_BACKS4
  2051.     CALL    EMS_SAVE
  2052.     PUSH    EAX
  2053.     MOV    EAX,SAM_OFS4
  2054.     CALL    EMS_PAGING
  2055.     POP    EAX
  2056.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  2057.     MOV    DX,SAM_FRQ4        ;OFF ADD AFTER FIXED POINT (X/256)
  2058.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  2059.     MOV    DH,SAM_OFL4        ;ACTUAL AFTER FIXED POINT VALUE
  2060.     MOV    BX,SAM_MAX4        ;COUNTER FOR SAMPLE ENDING
  2061.     MOV    DI,DMA_PTR
  2062.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  2063.     PUSH    CX SI
  2064. MIX_LOOPS4:
  2065.     MOV    AL,ES:[SI]
  2066.     ADD    DH,DL
  2067.     ADC    SI,BP
  2068.     SUB    DH,DL
  2069.     ADD    DH,DL
  2070.     SBB    BX,BP
  2071.     JC    SHORT MIX_ENDS4
  2072.     JZ    SHORT MIX_ENDS4
  2073.     MOV    AH,ES:[SI]
  2074.     ADD    DH,DL
  2075.     ADC    SI,BP
  2076.     ADD    [DI],AL
  2077.     JNO    SHORT MIX_OS41
  2078.     SHR    AL,7
  2079.     ADD    AL,7FH
  2080.     MOV    [DI],AL
  2081. MIX_OS41:
  2082.     ADD    [DI+1],AH
  2083.     JNO    SHORT MIX_OS42
  2084.     SHR    AH,7
  2085.     ADD    AH,7FH
  2086.     MOV    [DI+1],AH
  2087. MIX_OS42:
  2088.     ADD    DI,4
  2089.     SUB    DH,DL
  2090.     ADD    DH,DL
  2091.     SBB    BX,BP
  2092.     JC    SHORT MIX_ENDS4
  2093.     JZ    SHORT MIX_ENDS4
  2094.     LOOP    MIX_LOOPS4
  2095. MIX_REST4:
  2096.     MOV    AX,CS
  2097.     MOV    DS,AX
  2098.     MOV    SAM_OFL4,DH
  2099.     POP    AX CX
  2100.     SUB    SI,AX
  2101.     PUSH    EAX
  2102.     MOVZX    EAX,SI
  2103.     ADD    SAM_OFS4,EAX
  2104.     POP    EAX
  2105.     MOV    SAM_MAX4,BX
  2106.     CALL    EMS_RESTORE
  2107. GO_BACKS4:
  2108.     RET
  2109. MIX_ENDS4:
  2110.     MOV    CS:SAM_SEG4,0
  2111.     JMP    MIX_REST4
  2112. MIX_CHANNELS4 ENDP
  2113. ;-----------------------------------------------------------------------------
  2114. ; SET EMS-PAGES
  2115. ; IN:  EAX= EMS-OFFSET
  2116. ; OUT: ES:DI= SEGMENT & OFFSET IN EMS PAGE
  2117. ;-----------------------------------------------------------------------------
  2118. EMS_PAGING PROC NEAR
  2119.     MOV    DI,AX
  2120.     AND    DI,3FFFH
  2121.     MOV    ES,EMS_SEG
  2122.     PUSHA
  2123.     PUSH    EAX
  2124.     SHR    EAX,14
  2125.     MOV    BX,AX
  2126.     XOR    AL,AL
  2127.     MOV    DX,EMS_HANDLE
  2128.     MOV    AH,44H
  2129.     INT    67H
  2130.     INC    AL
  2131.     INC    BX
  2132.     MOV    AH,44H
  2133.     INT    67H
  2134.     INC    AL
  2135.     INC    BX
  2136.     MOV    AH,44H
  2137.     INT    67H
  2138.     INC    AL
  2139.     INC    BX
  2140.     MOV    AH,44H
  2141.     INT    67H
  2142.     POP    EAX
  2143.     POPA
  2144.     RET
  2145. EMS_PAGING ENDP
  2146. ;-----------------------------------------------------------------------------
  2147. EMS_SAVE PROC NEAR
  2148.     PUSH    AX DX
  2149.     MOV    DX,EMS_HANDLE        ;EMS MAPPING SICHERN
  2150.     MOV    AH,47H
  2151.     INT    67H
  2152.     POP    DX AX
  2153.     RET
  2154. EMS_SAVE ENDP
  2155. ;-----------------------------------------------------------------------------
  2156. EMS_RESTORE PROC NEAR
  2157.     PUSH    AX DX
  2158.     MOV    DX,EMS_HANDLE        ;EMS MAPPING ZURÜCKSETZEN
  2159.     MOV    AH,48H
  2160.     INT    67H
  2161.     POP    DX AX
  2162.     RET
  2163. EMS_RESTORE ENDP
  2164. ;╒═══════════════════════════════════════════════════════════════════════════╕
  2165. ;│ DESCRIPTION: Calculates the values for the mixing multiplication table.   │
  2166. ;│              This table is used during 4/8-channel mixing to speed up the │
  2167. ;│              operation by avoiding 'mul' instructions.                    │
  2168. ;╘═══════════════════════════════════════════════════════════════════════════╛
  2169. MAKE_MIXMUL_VOLUMETABLE PROC NEAR
  2170.     MOV    ES,DMA_SEG
  2171.     MOV    DI,MIXMUL_OFFSET
  2172.     CLD
  2173.     XOR    BX,BX            ; start with volume 0
  2174.     INC    BH
  2175. VOLUMELOOP:                ; start with sample 0
  2176. SAMPLELOOP:
  2177.     MOV    AL,BL
  2178.     IMUL    BH
  2179.     SAL    AX,1
  2180.     OR    AH,AH            ; ROUND UP
  2181.     JNS    SHORT GMK1
  2182.     OR    AL,AL
  2183.     JZ    SHORT GMK1
  2184.     INC    AH
  2185. GMK1:    CMP    BH,1
  2186.     JA    SHORT GMK2
  2187.     XOR    AX,AX
  2188. GMK2:    MOV    AL,AH
  2189.     STOSB
  2190.     INC    BL
  2191.     JNZ    SAMPLELOOP
  2192.     INC    BH
  2193.     CMP    BH,64
  2194.     JBE    VOLUMELOOP
  2195.     RET
  2196. MAKE_MIXMUL_VOLUMETABLE ENDP
  2197. ;=============================================================================
  2198.  
  2199.  
  2200. ;=============================================================================
  2201. ;
  2202. ; DOS ROUTINEN
  2203. ;
  2204. ;=============================================================================
  2205. ;-----------------------------------------------------------------------------
  2206. ; TIMER-IRQ-HANDLER: 1024 HZ CALLING FREQUENCE
  2207. ;-----------------------------------------------------------------------------
  2208. TIMER_HANDLER PROC FAR
  2209.     PUSH    AX
  2210.     CMP    CS:SYSTEM,0
  2211.     JNE    SHORT WT6
  2212.     MOV    AL,UHR_STATC
  2213.     OUT    UHR_INDEX,AL
  2214.     JMP    SHORT WT1
  2215. WT1:    JMP    SHORT WT2
  2216. WT2:    IN    AL,UHR_PORT
  2217. WT6:    MOV     AL,20H
  2218.     OUT     IRQ3,AL
  2219.     OUT    IRQ1,AL
  2220.     STI
  2221.     CMP    CS:MOD_STAT,0
  2222.     JE    SHORT WT3
  2223.     MOV    AX,WORD PTR CS:[BPM_SPEED+2]    ;1024/20.48 = 50 HZ
  2224.     ADD    WORD PTR CS:[BPM_COUNT+2],AX
  2225.     MOV    AX,WORD PTR CS:[BPM_SPEED]
  2226.     ADC    WORD PTR CS:[BPM_COUNT],AX
  2227.     JNC    SHORT WT3
  2228.     CMP    CS:IRQ_REENTER,0
  2229.     JNE    SHORT WT3
  2230.     MOV    CS:IRQ_REENTER,1
  2231.     PUSHA
  2232.     PUSH    DS ES CS
  2233.     POP    DS
  2234.     CALL    CONTROL_CHANNELS
  2235. ;    MOV    AH,7
  2236. ;    CALL    RASTER_COL
  2237.     CALL    MIXUP_CHANNELS
  2238. ;    MOV    AH,0
  2239. ;    CALL    RASTER_COL
  2240.     TEST    SB_MODUS,2
  2241.     JZ    SHORT WT5
  2242.     MOV    MOD_STAT,4
  2243.     JMP    SHORT WT4
  2244. WT5:    CMP    MOD_STAT,4
  2245.     JB    SHORT WT4
  2246.     MOV    MOD_STAT,2
  2247. WT4:    POP    ES DS
  2248.     POPA
  2249.     MOV    CS:IRQ_REENTER,0
  2250. WT3:    POP    AX
  2251.     CMP    CS:VAR_BUFSEG,0
  2252.     JNE    SHORT WT8
  2253.     CMP    CS:SYSTEM,0
  2254.     JE    SHORT WT7
  2255.     DEC    CS:IRQCOUNT
  2256.     JNZ    SHORT WT7
  2257.     MOV    CS:IRQCOUNT,56
  2258. WT8:    JMP    DWORD PTR CS:[HOLD70]
  2259. WT7:    IRET
  2260. TIMER_HANDLER ENDP
  2261. ;-----------------------------------------------------------------------------
  2262. ; SOUNDBLASTER-IRQ-HANDLER
  2263. ;-----------------------------------------------------------------------------
  2264. SBIRQ_HANDLER PROC FAR
  2265.     PUSH    AX CX DX
  2266.     MOV    DX,CS:SB_RSTAT        ;CLEAR IRQ
  2267.     IN    AL,DX
  2268.     CMP    CS:SBPRO_FLAG,1
  2269.     JE    SHORT WUV4
  2270.     DEC    DX
  2271.     DEC    DX
  2272.     MOV    CX,1000H
  2273. WUV1:    IN    AL,DX
  2274.     OR    AL,AL
  2275.     JNS    SHORT WUW1
  2276.     LOOP    WUV1
  2277. WUW1:    MOV    AL,14H            ;SB MONO
  2278.     OUT    DX,AL
  2279.     MOV    CX,1000H
  2280. WUV2:    IN    AL,DX            ;WAIT UNTIL READY
  2281.     OR    AL,AL
  2282.     JNS    SHORT WUW2
  2283.     LOOP    WUV2
  2284. WUW2:    MOV    AL,0F0H            ;SET MAX BLOCK SIZE
  2285.     OUT    DX,AL
  2286.     MOV    CX,1000H
  2287. WUV3:    IN    AL,DX            ;WAIT UNTIL READY
  2288.     OR    AL,AL
  2289.     JNS    SHORT WUW3
  2290.     LOOP    WUV3
  2291. WUW3:    MOV    AL,0FFH
  2292.     OUT    DX,AL
  2293. WUV4:    MOV    AL,20H
  2294.     CMP    CS:IRQ_NUMBER,8
  2295.     JB    SHORT WUV5
  2296.     OUT    IRQ3,AL
  2297. WUV5:    OUT    IRQ1,AL
  2298.     POP    DX CX AX
  2299.     IRET
  2300. COMMENT *                ;MIT AUTOINIT PCM IST RESTART UNNÖTIG
  2301. WUV4:    MOV    AL,48H            ;SB STEREO
  2302.     OUT    DX,AL
  2303.     MOV    CX,1000H
  2304. WUV5:    IN    AL,DX            ;WAIT UNTIL READY
  2305.     OR    AL,AL
  2306.     JNS    SHORT WUW5
  2307.     LOOP    WUV5
  2308. WUW5:    MOV    AL,0F0H            ;SET MAX BLOCK SIZE
  2309.     OUT    DX,AL
  2310.     MOV    CX,1000H
  2311. WUV6:    IN    AL,DX            ;WAIT UNTIL READY
  2312.     OR    AL,AL
  2313.     JNS    SHORT WUW6
  2314.     LOOP    WUV6
  2315. WUW6:    MOV    AL,0FFH
  2316.     OUT    DX,AL
  2317.     MOV    CX,1000H
  2318. WUV7:    IN    AL,DX            ;WAIT UNTIL READY
  2319.     OR    AL,AL
  2320.     JNS    SHORT WUW7
  2321.     LOOP    WUV7
  2322. WUW7:    MOV    AL,91H            ;START SBPRO
  2323.     OUT    DX,AL
  2324.     MOV    AL,20H
  2325.     OUT    IRQ1,AL
  2326.     POP    DX CX AX
  2327.     IRET
  2328.     *
  2329. SBIRQ_HANDLER ENDP
  2330. ;-----------------------------------------------------------------------------
  2331. ; SERVICE IRQ UMLEITUNG; USES THE REAL-TIME-CLOCK IRQ
  2332. ;-----------------------------------------------------------------------------
  2333. IRQ_INIT PROC NEAR
  2334.     CLI
  2335.     XOR     AX,AX
  2336.     MOV     ES,AX
  2337.     CMP    SYSTEM,0
  2338.     JNE    WU11
  2339.     MOV     AX,COMP_SPEED2        ;XCHANGE INIT & STOP DATA FOR DOS
  2340.     MOV     DX,COMP_SPEED3
  2341.     MOV     COMP_SPEED2,DX
  2342.     MOV     COMP_SPEED3,AX
  2343.     CMP    VAR_BUFSEG,0
  2344.     JNE    SHORT WU13
  2345.     MOV    AL,UHR_STATA        ;UHR-IRQ-RATE EINSTELLEN (1024 HZ)
  2346.     OUT    UHR_INDEX,AL
  2347.     JMP    SHORT WU1
  2348. WU1:    JMP    SHORT WU2
  2349. WU2:    XCHG    AL,AH
  2350.     IN    AL,UHR_PORT
  2351.     AND    AL,0F0H
  2352.     OR    AL,DL
  2353.     XCHG    AL,AH
  2354.     OUT    UHR_INDEX,AL
  2355.     JMP    SHORT WU3
  2356. WU3:    JMP    SHORT WU4
  2357. WU4:    XCHG    AL,AH
  2358.     OUT    UHR_PORT,AL
  2359.     JMP    SHORT WU5
  2360. WU5:    JMP    SHORT WU6
  2361. WU6:    MOV    AL,UHR_STATB        ;UHR-IRQ-MODUS EINSTELLEN
  2362.     OUT    UHR_INDEX,AL
  2363.     JMP    SHORT WU7
  2364. WU7:    JMP    SHORT WU8
  2365. WU8:    XCHG    AL,AH
  2366.     IN    AL,UHR_PORT
  2367.     AND    AL,08FH
  2368.     MOV    DL,DH
  2369.     AND    DL,40H
  2370.     OR    AL,DL
  2371.     XCHG    AL,AH
  2372.     OUT    UHR_INDEX,AL
  2373.     JMP    SHORT WU9
  2374. WU9:    JMP    SHORT WU10
  2375. WU10:    XCHG    AL,AH
  2376.     OUT    UHR_PORT,AL
  2377.     IN    AL,IRQ4            ;IRQ8 DE-/MASKIEREN
  2378.     AND    AL,0FEH
  2379.     MOV    DL,DH
  2380.     AND    DL,1
  2381.     OR    AL,DL
  2382.     OUT    IRQ4,AL
  2383. WU13:    MOV    DL,DH
  2384.     AND    DL,1
  2385.     MOV    CL,IRQ_NUMBER
  2386.     CMP    CL,8
  2387.     JAE    SHORT WU20
  2388.     IN    AL,IRQ2            ;SBIRQ 0-7 DE-/MASKIEREN
  2389.     SHL    DL,CL
  2390.     MOV    DH,0FEH
  2391.     ROL    DH,CL
  2392.     AND    AL,DH
  2393.     OR    AL,DL
  2394.     OUT    IRQ2,AL
  2395.     JMP    SHORT WU21
  2396. WU20:    SUB    CL,8            ;SBIRQ 8-15 DE-/MASKIEREN
  2397.     IN    AL,IRQ4
  2398.     SHL    DL,CL
  2399.     MOV    DH,0FEH
  2400.     ROL    DH,CL
  2401.     AND    AL,DH
  2402.     OR    AL,DL
  2403.     OUT    IRQ4,AL
  2404. WU21:    MOV     BX,4*70H                ;UHR-IRQ VERBIEGEN
  2405.     MOV     EAX,ES:[BX]
  2406.     MOV     EDX,HOLD70
  2407.     MOV     ES:[BX],EDX
  2408.     MOV     HOLD70,EAX
  2409.     JMP    WU12
  2410. WU11:    CMP    VAR_BUFSEG,0
  2411.     JNE    SHORT WU14
  2412.     MOV     AX,COMP_SPEED4        ;FOR WINDOWS
  2413.     MOV     DX,COMP_SPEED5
  2414.     MOV     COMP_SPEED4,DX
  2415.     MOV     COMP_SPEED5,AX
  2416.     MOV     AL,00110110B            ;TIMER0 AUF 1.024 KHZ EINSTELLEN
  2417.     OUT     PIT1,AL                 ;TEILER=1193
  2418.     MOV     AL,DL
  2419.     OUT     TIMER0,AL
  2420.     JMP     SHORT OUT40
  2421. OUT40:  MOV     AL,DH
  2422.     OUT     TIMER0,AL
  2423. WU14:    MOV     AX,COMP_SPEED2        ;XCHANGE INIT & STOP DATA FOR DOS
  2424.     MOV     DX,COMP_SPEED3
  2425.     MOV     COMP_SPEED2,DX
  2426.     MOV     COMP_SPEED3,AX
  2427.     MOV    DL,DH
  2428.     AND    DL,1
  2429.     MOV    CL,IRQ_NUMBER
  2430.     CMP    CL,8
  2431.     JAE    SHORT WU30
  2432.     IN    AL,IRQ2            ;SBIRQ 0-7 DE-/MASKIEREN
  2433.     SHL    DL,CL
  2434.     MOV    DH,0FEH
  2435.     ROL    DH,CL
  2436.     AND    AL,DH
  2437.     OR    AL,DL
  2438.     OUT    IRQ2,AL
  2439.     JMP    SHORT WU31
  2440. WU30:    SUB    CL,8
  2441.     IN    AL,IRQ4            ;SBIRQ 8-15 DE-/MASKIEREN
  2442.     SHL    DL,CL
  2443.     MOV    DH,0FEH
  2444.     ROL    DH,CL
  2445.     AND    AL,DH
  2446.     OR    AL,DL
  2447.     OUT    IRQ4,AL
  2448. WU31:    MOV     BX,4*8H                 ;TIMEOUT-IRQ VERBIEGEN
  2449.     MOV     EAX,ES:[BX]
  2450.     MOV     EDX,HOLD70
  2451.     MOV     ES:[BX],EDX
  2452.     MOV     HOLD70,EAX
  2453. WU12:    MOVZX    BX,CL            ;SOUNDBLASTER-IRQ VERBIEGEN
  2454.     ADD    BX,08H
  2455.     CMP    IRQ_NUMBER,8
  2456.     JB    SHORT WU40
  2457.     ADD    BX,68H
  2458. WU40:    SHL    BX,2
  2459.     MOV     EAX,ES:[BX]
  2460.     MOV     EDX,HOLDSB
  2461.     MOV     ES:[BX],EDX
  2462.     MOV     HOLDSB,EAX
  2463.     MOV    AL,20H
  2464.     OUT    IRQ3,AL
  2465.     OUT    IRQ1,AL
  2466.     STI
  2467.     RET
  2468. IRQ_INIT ENDP
  2469. ;----------------------------------------------------------------------------
  2470. ; RESERVIERT SPEICHER FÜR TRACKS, CARRY-FLAG 0=OK 1=ABBRUCH
  2471. ;----------------------------------------------------------------------------
  2472. SET_TMEM PROC NEAR
  2473.     MOV     AH,48H
  2474.     MOV     BX,1000H                ;64K TRACK BUFFER (WIRD RESIZED)
  2475.     INT     21H
  2476.     JC      SHORT STCM1
  2477.     MOV     TRACK_SEG,AX
  2478.     MOV    AH,48H
  2479.     MOV    BX,80H            ;2K PATTERN BUFFER
  2480.     INT    21H
  2481.     JC    SHORT STCM1
  2482.     MOV    PATTERN_SEG,AX
  2483. STCM1:  RET
  2484. SET_TMEM ENDP
  2485. ;----------------------------------------------------------------------------
  2486. ; GIBT SPEICHER VON TRACKS WIEDER FREI
  2487. ;----------------------------------------------------------------------------
  2488. FREE_TMEM PROC NEAR
  2489.     MOV    AX,SAMPLE_SEG
  2490.     MOV    ES,AX
  2491.     MOV    AH,49H
  2492.     INT    21H
  2493.     MOV     AX,TRACK_SEG
  2494.     MOV     ES,AX
  2495.     MOV     AH,49H
  2496.     INT     21H
  2497.     RET
  2498. FREE_TMEM ENDP
  2499. ;----------------------------------------------------------------------------
  2500. ; RESERVIERT SPEICHER FÜR DMA_BUFFER & MIXMUL_TABLE, CARRY 0=OK 1=ABBRUCH
  2501. ;----------------------------------------------------------------------------
  2502. SET_DMEM PROC NEAR
  2503.     MOV     AH,48H
  2504.     MOV     BX,0600H                ;24K BUFFER
  2505.     INT     21H
  2506.     JC      SHORT SDCM1
  2507.     MOV     DMA_SEG,AX
  2508.     MOV    DMA_OFFSET,0        ;DMA_BUFFER CA.  8K
  2509.     MOV    MIXMUL_OFFSET,2000H    ;MIXMUL_TAB CA. 16K
  2510.     AND    AX,0FFFH        ;ES IST DARAUF ZU ACHTEN, DASS
  2511.     CMP    AX,0E00H        ;DER DMA_BUFFER VOLLSTÄNDIG IN
  2512.     JB    SHORT SDCM2        ;EINER PAGE LIEGT
  2513.     MOV    DMA_OFFSET,4000H
  2514.     MOV    MIXMUL_OFFSET,0
  2515. SDCM2:    CLC
  2516. SDCM1:  RET
  2517. SET_DMEM ENDP
  2518. ;----------------------------------------------------------------------------
  2519. ; GIBT SPEICHER VON DMA & MIXMUL_VOLUMETABLE WIEDER FREI
  2520. ;----------------------------------------------------------------------------
  2521. FREE_DMEM PROC NEAR
  2522.     MOV    AX,DMA_SEG
  2523.     MOV    ES,AX
  2524.     MOV    AH,49H
  2525.     INT    21H
  2526.     RET
  2527. FREE_DMEM ENDP
  2528. ;-----------------------------------------------------------------------------
  2529. FREE_MEM PROC NEAR
  2530.     MOV     BX,PROG_END_SEG         ;SPEICHER FREI MACHEN
  2531.     SUB     BX,PROG_START_SEG
  2532.     MOV     ES,PROG_START_SEG
  2533.     MOV     AH,4AH                  ;SPEICHERBLOCKGRÖSSE ÄNDERN
  2534.     INT     21H
  2535.     RET
  2536. FREE_MEM ENDP
  2537. ;=============================================================================
  2538.  
  2539.  
  2540.  
  2541. ;=============================================================================
  2542. ;
  2543. ; SOUNDBLASTER HARDWARE ROUTINEN
  2544. ;
  2545. ;=============================================================================
  2546. ; SET MIXER IF PRESENT
  2547. ;-----------------------------------------------------------------------------
  2548. MIXER_INIT PROC NEAR
  2549.     MOV    DX,SBP_MIXERI
  2550. COMMENT *                
  2551.     XOR    AL,AL            ;RESET MIXER AUSGEBAUT WEGEN
  2552.     OUT    DX,AL            ;UNZULÄNGLICHER EINSTELLUNG
  2553.     MOV    CX,100            ;VON SB16 ASP (GAIN x2,x3,..)
  2554.     CALL    WAIT_TIME
  2555.     MOV    DX,SBP_MIXERD
  2556.     XOR    AL,AL
  2557.     OUT    DX,AL
  2558.     DEC    DX
  2559.     *
  2560.     MOV    AL,22H
  2561.     OUT    DX,AL
  2562.     INC    DX
  2563.     MOV    AL,255            ;MAX MASTERVOLUME
  2564.     OUT    DX,AL
  2565.     DEC    DX
  2566.     MOV    AL,4
  2567.     OUT    DX,AL
  2568.     INC    DX
  2569.     MOV    AL,255            ;MAX DSPVOLUME
  2570.     OUT    DX,AL
  2571.     DEC    DX
  2572.     MOV    AL,0EH
  2573.     OUT    DX,AL
  2574.     INC    DX
  2575.     MOV    AL,0H            ;FILTER & MONO
  2576.     MOV    SBPRO_FLAG,AL
  2577.     CMP    SB_TYP,1        ;SBPRO ENABLED?
  2578.     JE    SHORT GMIX1
  2579.     MOV    SBPRO_FLAG,1
  2580.     MOV    AL,2H            ;FILTER & STEREO
  2581. GMIX1:    OUT    DX,AL
  2582.     RET
  2583. MIXER_INIT ENDP
  2584. ;-----------------------------------------------------------------------------
  2585. ; SET DMA READY FOR TRANSFER WITH AUTOINIT
  2586. ; IN: DX:BX= BLOCKPOINTER, CX= SIZE
  2587. ;-----------------------------------------------------------------------------
  2588. DMA_INIT PROC NEAR
  2589.     MOV    AX,DX            ;ADRESSE IN PAGE UND OFFSET UMRECHNEN
  2590.     SHL    DX,4
  2591.     SHR    AH,4            ;PAGE
  2592.     ADD    BX,DX            ;OFFSET NEU
  2593.     ADC    AH,0
  2594.     MOV    DMA_PAGE,AH
  2595.     MOV    DMA_POFF,BX
  2596.     DEC    CX            ;DMA SIZE= BLOCK SIZE -1
  2597.     MOV    AL,DMA_CHANNEL
  2598.     OR    AL,4
  2599.     OUT    0AH,AL            ;DMA-KANAL MASKIEREN
  2600.     AND    AL,3
  2601.     OR    AL,01011000B
  2602.     OUT    0BH,AL            ;DMA-MODUS FÜR SB
  2603.     OUT    0CH,AL            ;FLIP-FLOP LÖSCHEN
  2604.     AND    AL,3
  2605.     MOVZX    DX,AL
  2606.     SHL    DL,1
  2607.     MOV    AL,BL            ;DMA CHANNEL 1-4
  2608.     OUT    DX,AL            ;OFFSET LOW
  2609.     MOV    AL,BH
  2610.     OUT    DX,AL            ;OFFSET HIGH
  2611.     INC    DL
  2612.     MOV    AL,CL
  2613.     OUT    DX,AL            ;SIZE LOW
  2614.     MOV    AL,CH
  2615.     OUT    DX,AL            ;SIZE HIGH
  2616.     MOV    BX,DX
  2617.     SHR    BL,1
  2618.     MOV    DL,[DMA_DATA+BX]
  2619.     MOV    AL,AH
  2620.     OUT    DX,AL            ;PAGE
  2621.     MOV    AL,BL
  2622.     OUT    0AH,AL            ;DMA-KANAL DEMASKIEREN
  2623.     RET
  2624. DMA_INIT ENDP
  2625. ;-----------------------------------------------------------------------------
  2626. ; DSP SET SAMPLE RATE
  2627. ; IN: AH= RATE (= 256-(1000000/FREQ))
  2628. ;-----------------------------------------------------------------------------
  2629. DSP_RATE PROC NEAR
  2630.     CMP    SB_VERSION,4
  2631.     JAE    SHORT GDSPR1
  2632.     PUSH    AX
  2633.     MOV    AH,40H
  2634.     CALL    DSP_WRITE
  2635.     POP    AX
  2636.     CALL    DSP_WRITE
  2637.     RET
  2638. GDSPR1:    MOV    AH,41H            ;DSP 4.0 (SB16)
  2639.     CALL    DSP_WRITE
  2640.     MOV    AX,SAMPLE_RATE
  2641.     CALL    DSP_WRITE
  2642.     MOV    AX,SAMPLE_RATE
  2643.     MOV    AH,AL
  2644.     CALL    DSP_WRITE
  2645.     RET
  2646. DSP_RATE ENDP
  2647. ;-----------------------------------------------------------------------------
  2648. ; DSP OUT BLOCK
  2649. ;-----------------------------------------------------------------------------
  2650. DSP_OUT PROC NEAR
  2651.     CMP    SBPRO_FLAG,1
  2652.     JE    SHORT GDSP1
  2653.     MOV    AH,14H            ;MONO DMA-AUSGABE NEU STARTEN
  2654.     CALL    DSP_WRITE        ;ONE CYCLE= 14H, AUTOINIT= 48H,..,1CH
  2655.     MOV    AH,0F0H            ;SIZE LOW
  2656.     CALL    DSP_WRITE
  2657.     MOV    AH,0FFH            ;SIZE HIGH
  2658.     CALL    DSP_WRITE
  2659.     RET
  2660. GDSP1:    CMP    SB_VERSION,4
  2661.     JAE    SHORT GDSP2
  2662.     MOV    AH,48H            ;STEREO DMA-AUSGABE NEU STARTEN
  2663.     CALL    DSP_WRITE
  2664.     MOV    AH,0F0H            ;SIZE LOW
  2665.     CALL    DSP_WRITE
  2666.     MOV    AH,0FFH            ;SIZE HIGH
  2667.     CALL    DSP_WRITE
  2668.     MOV    AH,90H            ;START MIT AUTOINIT PCM= 90H
  2669.     CALL    DSP_WRITE        ;         ONE CYCLE PCM= 91H
  2670.     RET
  2671. GDSP2:    MOV    AH,0C6H            ;8 BIT PCM, AUTOINIT FOR DSP 4.0
  2672.     CALL    DSP_WRITE
  2673.     MOV    AH,20H            ;STEREO UNSIGNED
  2674.     CALL    DSP_WRITE
  2675.     MOV    AH,0F0H            ;SIZE LOW
  2676.     CALL    DSP_WRITE
  2677.     MOV    AH,0FFH            ;SIZE HIGH
  2678.     CALL    DSP_WRITE
  2679.     RET
  2680. DSP_OUT ENDP
  2681. ;-----------------------------------------------------------------------------
  2682. ; DSP RESET
  2683. ; OUT: CARRY 1= FAILURE
  2684. ;-----------------------------------------------------------------------------
  2685. DSP_RESET PROC NEAR
  2686.     CALL    DSP_OFF
  2687.     OUT    0DH,AL            ;DMA MASTER CLEAR
  2688.     CALL    MIXER_INIT
  2689.     MOV    DX,SB_RESET
  2690.     MOV    AL,1
  2691.     OUT    DX,AL            ;SEND RESET COMMAND
  2692.     MOV    CX,4
  2693.     CALL    WAIT_TIME        ;WAIT
  2694.     XOR    AL,AL
  2695.     OUT    DX,AL            ;CLEAR RESET COMMAND
  2696.     MOV    CX,120
  2697.     CALL    WAIT_TIME        ;WAIT
  2698.     MOV    DX,SB_RSTAT
  2699.     IN    AL,DX            ;CHECK IF SUCCESSFUL
  2700.     OR    AL,AL
  2701.     JNS    SHORT GDRES1
  2702.     MOV    DX,SB_READ
  2703.     IN    AL,DX
  2704.     CMP    AL,0AAH
  2705.     JNE    SHORT GDRES1
  2706.     MOV    AH,0E1H            ;GET DSP VERSION
  2707.     CALL    DSP_WRITE
  2708.     CALL    DSP_READ
  2709.     MOV    SB_VERSION,AL
  2710.     CALL    DSP_READ
  2711.     CALL    DSP_ON
  2712.     CLC                ;RESET OK
  2713.     RET
  2714. GDRES1:    STC                ;RESET FAILURE
  2715.     RET
  2716. DSP_RESET ENDP
  2717. ;-----------------------------------------------------------------------------
  2718. ; LAUTSPRECHER EIN
  2719. ;-----------------------------------------------------------------------------
  2720. DSP_ON PROC NEAR
  2721.     MOV    AH,0D1H            ;SPEAKER ON
  2722.     CALL    DSP_WRITE
  2723.     MOV    CX,120
  2724.     CALL    WAIT_TIME        ;WAIT
  2725.     RET
  2726. DSP_ON ENDP
  2727. ;-----------------------------------------------------------------------------
  2728. ; LAUTSPRECHER AUS
  2729. ;-----------------------------------------------------------------------------
  2730. DSP_OFF PROC NEAR
  2731.     PUSH    CS
  2732.     POP    DS
  2733.     CMP    SB_TYP,1
  2734.     JNE    SHORT GDSPF1        ;SB
  2735.     MOV    AL,DMA_CHANNEL        ;DMA DEMASKIEREN
  2736.     OUT    0AH,AL
  2737.     MOV    AH,0D0H            ;DMA AUSGABE STOPPEN
  2738.     CALL    DSP_WRITE
  2739.     MOV    AH,0D3H            ;DSP OFF
  2740.     CALL    DSP_WRITE
  2741.     MOV    CX,240
  2742.     CALL    WAIT_TIME        ;WAIT
  2743.     RET
  2744. GDSPF1:    MOV    DX,SBP_MIXERI        ;SBPRO
  2745.     CMP    LOADMOD_FLAG,0
  2746.     JNE    SHORT GDSPF2
  2747.     MOV    AL,22H            ;AUSGEBAUT WEGEN CD UNTERBRECHUNG
  2748.     OUT    DX,AL
  2749.     INC    DX
  2750.     MOV    AL,0            ;MIN MASTERVOLUME
  2751.     OUT    DX,AL
  2752.     DEC    DX
  2753. GDSPF2:    MOV    AL,4
  2754.     OUT    DX,AL
  2755.     INC    DX
  2756.     MOV    AL,0            ;MIN DSPVOLUME
  2757.     OUT    DX,AL
  2758.     MOV    DX,SB_RESET
  2759.     MOV    AL,1
  2760.     OUT    DX,AL            ;SEND RESET COMMAND
  2761.     MOV    CX,4
  2762.     CALL    WAIT_TIME        ;WAIT
  2763.     XOR    AL,AL
  2764.     OUT    DX,AL            ;CLEAR RESET COMMAND
  2765.     MOV    CX,120
  2766.     CALL    WAIT_TIME        ;WAIT
  2767.     MOV    AH,0D3H            ;DSP OFF
  2768.     CALL    DSP_WRITE
  2769.     MOV    CX,240
  2770.     CALL    WAIT_TIME
  2771.     RET
  2772. DSP_OFF ENDP
  2773. ;-----------------------------------------------------------------------------
  2774. ; READ BYTE
  2775. ; OUT: AL= BYTE
  2776. ;-----------------------------------------------------------------------------
  2777. DSP_READ PROC NEAR
  2778.     MOV    DX,SB_READ
  2779.     MOV    CX,-1            ;FAIL SAFE
  2780. LDRD1:    IN    AL,DX
  2781.     CMP    AL,0AAH
  2782.     JNE    SHORT LDRD2
  2783.     LOOP    LDRD1
  2784. LDRD2:    RET
  2785. DSP_READ ENDP
  2786. ;-----------------------------------------------------------------------------
  2787. ; WRITE BYTE
  2788. ; IN: AH= BYTE
  2789. ;-----------------------------------------------------------------------------
  2790. DSP_WRITE PROC NEAR
  2791.     MOV    DX,SB_WRITE
  2792.     MOV    CX,1000H        ;FAIL SAFE
  2793. LDWR1:    IN    AL,DX
  2794.     OR    AL,AL
  2795.     JNS    SHORT LDWR2
  2796.     LOOP    LDWR1
  2797. LDWR2:    MOV    AL,AH
  2798.     OUT    DX,AL
  2799.     RET
  2800. DSP_WRITE ENDP
  2801. ;-----------------------------------------------------------------------------
  2802. ; WAIT TIME
  2803. ; CX = XXX MILLISECONDS
  2804. ;-----------------------------------------------------------------------------
  2805. WAIT_TIME PROC NEAR
  2806.     PUSH    AX BX EDX
  2807. LWT1:    IN    AL,TIMER0
  2808.     MOV    BL,AL
  2809.     IN    AL,TIMER0
  2810.     MOV    BH,AL
  2811.     MOV    EDX,500000        ;FAIL SAFE
  2812. LWT2:    IN    AL,TIMER0        ;1 MILLISEC WARTEN
  2813.     XCHG    AL,AH
  2814.     IN    AL,TIMER0
  2815.     XCHG    AL,AH
  2816.     SUB    AX,BX
  2817.     NEG    AX
  2818.     DEC    EDX
  2819.     JZ    SHORT LWT3
  2820.     CMP    AX,1193
  2821.     JB    LWT2
  2822. LWT3:    LOOP    LWT1
  2823.     POP    EDX BX AX
  2824.     RET
  2825. WAIT_TIME ENDP
  2826. ;=============================================================================
  2827.  
  2828.  
  2829. ;=============================================================================
  2830. ;
  2831. ; MOD LADEROUTINEN
  2832. ;
  2833. ;=============================================================================
  2834. ; LÄDT EIN MODFILE
  2835. ; DS:DX= FILENAME
  2836. ;-----------------------------------------------------------------------------
  2837. LOAD_MOD PROC NEAR
  2838.     MOV    AX,3D00H        ;OPEN MOD
  2839.     INT    21H
  2840.     JC    GLDM1
  2841.     PUSH    CS
  2842.     POP    DS
  2843.     MOV    GDDHANDLE,AX
  2844. GLDM0:    CALL    SET_DMEM        ;ALLOCATE DMA-BUFFER 
  2845.     CALL    SET_TMEM        ;ALLOCATE TRACK-BUFFER
  2846.     MOV    BX,GDDHANDLE
  2847.     MOV    GDDZEIG,0
  2848.     CMP    LOADMOD_FLAG,0
  2849.     JNE    GLDM99
  2850.     MOV    CX,10            ;SONG-NAME HOLEN
  2851. LLDM1:    CALL    GET_QUEUE
  2852.     JC    GLDM2
  2853.     LOOP    LLDM1
  2854.     MOV    SAMPLE_SIZE,0
  2855.     XOR    SI,SI            ;31 INSTRUMENTS
  2856. LLDM2:    MOV    AX,SAMPLE_SIZE
  2857.     MOV    [SAMPLE_SEG+SI],AX
  2858.     MOV    CX,11            ;INSTRUMENT NAME
  2859. LLDM3:    CALL    GET_QUEUE    
  2860.     JC    GLDM2
  2861.     LOOP    LLDM3
  2862.     XOR    EAX,EAX
  2863.     CALL    GET_QUEUE        ;INSTRUMENT SIZE
  2864.     XCHG    AL,AH
  2865.     CMP    AX,2
  2866.     JAE    SHORT GLDM20
  2867.     XOR    AX,AX
  2868. GLDM20:    SHL    AX,1
  2869.     MOV    [ISIZE+SI],AX        ;HÖCHSTENS 64K
  2870.     OR    EAX,EAX
  2871.     JZ    SHORT GLDM9
  2872.     SHR    EAX,4
  2873.     INC    AX
  2874.     ADD    SAMPLE_SIZE,AX
  2875. GLDM9:    CALL    GET_QUEUE        ;IVOLUME & FINETUNE
  2876.     XCHG    AL,AH
  2877.     MOV    [IVOL_FINETUNE+SI],AX
  2878.     CALL    GET_QUEUE        ;ILOOP_START
  2879.     XCHG    AL,AH
  2880.     SHL    AX,1
  2881.     MOV    [ILOOP_START+SI],AX
  2882.     CALL    GET_QUEUE        ;ILOOP_SIZE
  2883.     XCHG    AL,AH
  2884.     SHL    AX,1
  2885.     MOV    [ILOOP_SIZE+SI],AX
  2886.     INC    SI
  2887.     INC    SI
  2888.     CMP    SI,62
  2889.     JB    LLDM2
  2890.     CALL    GET_QUEUE        ;SONG_SIZE & LOOP_BYTE OR NOTHING
  2891.     JC    GLDM2
  2892.     MOV    SONG_SIZE,AL
  2893.     MOV    SONG_LOOP,AH
  2894.     XOR    DX,DX
  2895.     MOV    CX,64            ;SONG_DATA
  2896.     MOV    DI,OFFSET SONG_DATA
  2897. LLDM4:    CALL    GET_QUEUE
  2898.     JC    GLDM2
  2899.     MOV    [DI],AX
  2900.     CMP    AL,DL            ;FIND HIGHEST PATTERN NUMBER
  2901.     JBE    SHORT GLDM12
  2902.     MOV    DL,AL
  2903. GLDM12:    CMP    AH,DL
  2904.     JBE    SHORT GLDM13
  2905.     MOV    DL,AH
  2906. GLDM13:    INC    DI
  2907.     INC    DI
  2908.     LOOP    LLDM4
  2909.     INC    DL
  2910.     CLD
  2911.     MOV    PATTERN_NUMBER,DX
  2912.     CALL    GET_QUEUE
  2913.     PUSH    AX
  2914.     CALL    GET_QUEUE
  2915.     SHL    EAX,16
  2916.     POP    AX
  2917.     MOV    MOD_SIGN,EAX
  2918.     CMP    EAX,"NHC8"        ;8CHN-MOD
  2919.     JE    SHORT GLDM3
  2920.     CMP    EAX,"8TLF"        ;FLT8-MOD
  2921.     JE    SHORT GLDM3
  2922.     CMP    EAX,".K.M"        ;M.K.-MOD
  2923.     JE    SHORT GLDM10
  2924.     CMP    EAX,"4TLF"        ;FLT4-MOD
  2925.     JNE    GLDM2
  2926.  
  2927. GLDM10:    MOV    CH_NUMB,4        ;4-CHANNEL-MOD
  2928.     MOV    PATTERN_SIZE,1024
  2929.     MOV    AH,0
  2930.     MOV    TRACK_INFO+4,AH
  2931.     MOV    TRACK_INFO+5,AH
  2932.     MOV    TRACK_INFO+6,AH
  2933.     MOV    TRACK_INFO+7,AH
  2934.     JMP    SHORT GLDM11
  2935. GLDM3:    MOV    CH_NUMB,8        ;8-CHANNEL-MOD: GET-PATTERNS
  2936.     MOV    PATTERN_SIZE,2048
  2937. GLDM11:    MOV    PATTERN_CURRENT,0
  2938.     MOV    TRACK_NUMBER,0
  2939. LLDM7:    MOV    ES,PATTERN_SEG
  2940.     MOV    BX,GDDHANDLE
  2941.     XOR    DI,DI
  2942. LLDM6:    XOR    SI,SI
  2943. LLDM5:    CALL    GET_QUEUE        ;PATTERN HOLEN UND IN TRACKS AUFSPALTEN
  2944.     JC    GLDM2
  2945.     MOV    DX,AX
  2946.     CALL    GET_QUEUE
  2947.     JC    GLDM2
  2948.     ROL    AL,4            ;MODIFY PATTERN DATA
  2949.     MOV    CL,AL            ;LOOK AT PROTRACKER-CODE HEADER
  2950.     AND    AL,0FH
  2951.     AND    CL,0F0H    
  2952.     MOV    CH,DL
  2953.     AND    DL,0FH
  2954.     AND    CH,0F0H
  2955.     OR    AL,CH
  2956.     OR    DL,CL
  2957.     XCHG    DL,DH
  2958.     PUSH    DI
  2959.     ADD    DI,SI
  2960.     SHL    EAX,16
  2961.     MOV    AX,DX
  2962.     STOSD
  2963.     POP    DI
  2964.     ADD    SI,256
  2965.     CMP    SI,PATTERN_SIZE        ;NEXT TRACK/CHANNEL
  2966.     JB    LLDM5
  2967.     ADD    DI,4            ;NEXT NOTE
  2968.     CMP    DI,256
  2969.     JB    LLDM6
  2970.     CALL    SET_FREQUENCIES
  2971.     MOV    ES,TRACK_SEG        ;TRACK1-8 INTEGRIEREN
  2972.     MOV    DX,TRACK_NUMBER
  2973.     XCHG    DL,DH
  2974.     MOV    DS,PATTERN_SEG
  2975.     XOR    SI,SI
  2976.     XOR    BX,BX
  2977. LLDM8:    XOR    DI,DI
  2978. LLDM9:    CMP    DX,DI
  2979.     JBE    SHORT GLDM4
  2980.     PUSH    SI DI
  2981.     MOV    CX,256/4
  2982.     REPE CMPSD            ;TRACK ALREADY EXISTS?
  2983.     POP    DI SI
  2984.     PUSHF
  2985.     ADD    DI,256
  2986.     POPF
  2987.     JNE    LLDM9
  2988.     JMP    SHORT GLDM5
  2989. GLDM4:    INC    DH            ;NO, ADD TRACK TO BUFFER
  2990.     PUSH    SI
  2991.     MOV    CX,256/4
  2992.     REP MOVSD
  2993.     POP    SI
  2994. GLDM5:    MOV    AX,DI            ;YES
  2995.     DEC    AH
  2996.     MOV    CS:[TRACK_INFO+BX],AH
  2997.     INC    BX
  2998.     ADD    SI,256
  2999.     CMP    BX,CS:CH_NUMB
  3000.     JB    LLDM8
  3001.     PUSH    CS
  3002.     POP    DS
  3003.     XCHG    DL,DH
  3004.     MOV    TRACK_NUMBER,DX
  3005.     XOR    BX,BX            ;TRACKLISTE NACHFÜHREN
  3006.     MOV    AX,PATTERN_CURRENT
  3007. LLDM10:    CMP    [SONG_DATA+BX],AL
  3008.     JNE    SHORT GLDM6
  3009.     MOV    AH,TRACK_INFO
  3010.     MOV    [TRACK1_DATA+BX],AH
  3011.     MOV    AH,TRACK_INFO+1
  3012.     MOV    [TRACK2_DATA+BX],AH
  3013.     MOV    AH,TRACK_INFO+2
  3014.     MOV    [TRACK3_DATA+BX],AH
  3015.     MOV    AH,TRACK_INFO+3
  3016.     MOV    [TRACK4_DATA+BX],AH
  3017.     MOV    AH,TRACK_INFO+4
  3018.     MOV    [TRACK5_DATA+BX],AH
  3019.     MOV    AH,TRACK_INFO+5
  3020.     MOV    [TRACK6_DATA+BX],AH
  3021.     MOV    AH,TRACK_INFO+6
  3022.     MOV    [TRACK7_DATA+BX],AH
  3023.     MOV    AH,TRACK_INFO+7
  3024.     MOV    [TRACK8_DATA+BX],AH
  3025. GLDM6:    INC    BX
  3026.     CMP    BL,128
  3027.     JB    LLDM10
  3028.     INC    PATTERN_CURRENT        ;NÄCHSTES PATTERN HOLEN
  3029.     MOV    AX,PATTERN_CURRENT
  3030.     CMP    AX,PATTERN_NUMBER
  3031.     JB    LLDM7
  3032.     JMP    SHORT GLDM7
  3033.  
  3034. GLDM99:    MOV    ES,TRACK_SEG        ;PATTERN SEGMENT WIEDER LÖSCHEN
  3035.     MOV    AH,49H
  3036.     INT    21H
  3037. GLDM7:    MOV    ES,PATTERN_SEG        ;PATTERN SEGMENT WIEDER LÖSCHEN
  3038.     MOV    AH,49H
  3039.     INT    21H
  3040.     CMP    LOADMOD_FLAG,0
  3041.     JNE    SHORT GLDM98
  3042.     MOV    BX,TRACK_NUMBER        ;TRACK SEGMENT REDUZIEREN
  3043.     SHL    BX,4
  3044.     MOV    ES,TRACK_SEG
  3045.     MOV    AH,4AH
  3046.     INT    21H
  3047.     MOV    BX,SAMPLE_SIZE        ;SAMPLE SEGMENT ALLOKIEREN 
  3048.     MOV    AH,48H
  3049.     INT    21H
  3050.     XOR    BX,BX
  3051. LLDM11:    ADD    [SAMPLE_SEG+BX],AX
  3052.     INC    BX
  3053.     INC    BX
  3054.     CMP    BX,62
  3055.     JB    LLDM11
  3056.     MOV    BX,GDDHANDLE
  3057.     XOR    SI,SI            ;SAMPLES LADEN
  3058. LLDM12:    MOV    CX,[ISIZE+SI]
  3059.     MOV    ES,[SAMPLE_SEG+SI]
  3060.     XOR    DI,DI
  3061.     SHR    CX,1
  3062.     JCXZ    SHORT GLDM8
  3063. LLDM13:    CALL    GET_QUEUE
  3064.     STOSW
  3065.     LOOP    LLDM13
  3066. GLDM8:    INC    SI
  3067.     INC    SI
  3068.     CMP    SI,62
  3069.     JB    LLDM12
  3070. GLDM98:    CLC
  3071.     JMP    SHORT GLDM15
  3072. GLDM2:    STC
  3073. GLDM15:    PUSHF
  3074.     CMP    VAR_BUFSEG,0
  3075.     JNE    SHORT GLDM16
  3076.     MOV    AH,3EH
  3077.     INT    21H
  3078. GLDM16:    POPF
  3079. GLDM1:    RET
  3080. LOAD_MOD ENDP
  3081. ;-----------------------------------------------------------------------------
  3082. ; ERSETZT DIE MEISTEN FREQUENZ-PERIODEN DURCH DEN TABELLEN-INDEX
  3083. ;-----------------------------------------------------------------------------
  3084. SET_FREQUENCIES PROC NEAR
  3085.     XOR    DI,DI
  3086. SET_FREQ1:
  3087.     MOV    AX,ES:[DI]        ;get fx
  3088.     MOV    DX,AX
  3089.     SHR    AH,4
  3090.     CMP    AH,3
  3091.     JE    SHORT SET_FREQ4
  3092.     CMP    AH,5
  3093.     JE    SHORT SET_FREQ4
  3094.     MOV    AX,DX
  3095.     AND    AX,0FFFH        ; Mask out unwanted bits.
  3096.     JZ    SHORT SET_FREQ4
  3097.     XOR    BX,BX
  3098.     MOV    CX,48            ; 36 periods to cycle through.
  3099. SET_FREQ2:
  3100.     CMP    AX,[MT_PERIODTABLE+BX]    ; Check the note against the period.
  3101.     JAE    SHORT SET_FREQ3        ; We found it!
  3102.     INC    BX            ; Otherwise, update the pointer and
  3103.     INC    BX
  3104.     LOOP    SET_FREQ2        ; keep looping.
  3105. SET_FREQ3:
  3106.     MOV    AX,DX            ;recall the Note Value
  3107.     AND    AX,0F000H        ;just keep fx
  3108.     INC    BX
  3109.     OR    AX,BX            ;put in the new offset
  3110.     STOSW                ;store it
  3111.     DEC    DI
  3112.     DEC    DI
  3113. SET_FREQ4:
  3114.     ADD    DI,4            ;and go to next channel
  3115.     CMP    DI,PATTERN_SIZE
  3116.     JB    SET_FREQ1
  3117.     RET
  3118. SET_FREQUENCIES ENDP
  3119. ;-----------------------------------------------------------------------------
  3120. ; HOLT EIN WORD AUS DEM BUFFER
  3121. ; IN: AX= WORD, BX= HANDLE
  3122. ;-----------------------------------------------------------------------------
  3123. GET_QUEUE PROC NEAR
  3124.     CMP     GDDZEIG,0
  3125.     JNE     SHORT GTQ1
  3126.     PUSH    CX DX
  3127.     MOV     DX,OFFSET QUEUE_BUFFER
  3128.     MOV     CX,256
  3129.     MOV     AH,3FH
  3130.     INT     21H
  3131.     MOV    GDDREST,AX
  3132.     POP    DX CX
  3133. GTQ1:   PUSH    BX
  3134.     MOV     BL,GDDZEIG
  3135.     XOR     BH,BH
  3136.     CMP    BX,GDDREST
  3137.     JAE    SHORT GTQ2
  3138.     MOV     AX,[QUEUE_BUFFER+BX]
  3139.     ADD     GDDZEIG,2
  3140.     POP    BX
  3141.     CLC
  3142.     RET
  3143. GTQ2:    POP    BX
  3144.     STC
  3145.     RET
  3146. GET_QUEUE ENDP
  3147. ;=============================================================================
  3148. ; LÄDT EIN SAMPLE
  3149. ; INPUT: DS:DX= FILENAME, CL= 00H AMIGA-SAMPLE, 80H PC-SAMPLE
  3150. ; OUTPUT: AX= SAMPLE-HANDLE FOR PLAYING
  3151. ;-----------------------------------------------------------------------------
  3152. LOAD_SAMPLE PROC NEAR
  3153.     MOV    AX,3D00H        ;OPEN SAMPLE
  3154.     INT    21H
  3155.     JC    GSMP1
  3156.     PUSH    CS
  3157.     POP    DS
  3158.     MOV    GDDHANDLE,AX
  3159.     MOV    BX,AX
  3160.     PUSH    CX
  3161.     CALL    GET_FILESIZE
  3162.     POP    CX
  3163. GSMP0:    AND    CL,80H
  3164.     MOV    SAM_FLAG1,CL
  3165.     MOV    GDDZEIG,0
  3166.     MOV    CX,AX
  3167.     AND    CX,0FFFEH
  3168.     SHR    AX,4
  3169.     INC    AX
  3170.     MOV    BX,AX
  3171.     CMP    EMS_SEG,0
  3172.     JNE    SHORT GSMP3
  3173.     PUSHA
  3174.     XOR    SI,SI
  3175.     XOR    AX,AX            ;CHECK FOR EMS-MANAGER
  3176.     MOV    ES,AX
  3177.     MOV    EMS_HANDLE,AX
  3178.     MOV    AX,ES:[4*67H+2]
  3179.     MOV    ES,AX
  3180.     CMP    ES:[10],"XMME"
  3181.     JNE    GSMP2
  3182.     CMP    ES:[14],"0XXX"
  3183.     JNE    GSMP2
  3184.     MOV    AH,42H
  3185.     INT    67H
  3186.     OR    AH,AH
  3187.     JNZ    GSMP2
  3188.     CMP    BX,41
  3189.     JB    GSMP2
  3190.     MOV    AH,41H
  3191.     INT    67H
  3192.     MOV    EMS_SEG,BX
  3193.     MOV    AH,43H            ;ALLOCATE 656K EMS FOR FX
  3194.     MOV    BX,41
  3195.     INT    67H
  3196.     MOV    EMS_HANDLE,DX
  3197.     XOR    AX,AX
  3198.     MOV    EMS_OFFSET,AX
  3199.     MOV    SAMPLE_ZEIG,AX
  3200.     POPA
  3201. GSMP3:    MOV    AX,EMS_OFFSET
  3202.     MOV    SI,SAMPLE_ZEIG
  3203.     MOV    [SAMPLE_MEM+SI],AX
  3204.     MOV    [SAMPLE_BIG+SI],CX
  3205.     ADD    SAMPLE_ZEIG,2
  3206.     MOV    DI,CX
  3207.     SHR    DI,4
  3208.     INC    DI
  3209.     ADD    EMS_OFFSET,DI
  3210.     XOR    DI,DI
  3211.     CLD
  3212.     INC    CX
  3213.     SHR    CX,1
  3214.     MOV    DL,SAM_FLAG1
  3215.     MOV    DH,DL
  3216.     MOVZX    BP,FX_VOL
  3217.     INC    BP
  3218.     AND    EAX,0FFFFH
  3219.     SHL    EAX,4
  3220. LSMP1:    PUSH    EAX
  3221.     OR    DI,DI
  3222.     JNZ    SHORT GSMP4
  3223.     CALL    EMS_PAGING
  3224. GSMP4:    MOV    BX,GDDHANDLE
  3225.     CALL    GET_QUEUE
  3226.     XOR    AX,DX
  3227.     SAR    AL,1
  3228.     SAR    AH,1
  3229.     PUSH    DX
  3230.     MOV    BL,AH
  3231.     CBW
  3232.     IMUL    BP
  3233.     MOV    AL,BL
  3234.     MOV    BL,AH
  3235.     CBW
  3236.     IMUL    BP
  3237.     MOV    AL,BL
  3238.     POP    DX
  3239.     STOSW
  3240.     POP    EAX
  3241.     INC    EAX
  3242.     INC    EAX
  3243.     LOOP    LSMP1
  3244.     CLC
  3245.     PUSHA
  3246. GSMP2:    POPA
  3247.     PUSHF
  3248.     CMP    VAR_BUFSEG,0
  3249.     JNE    SHORT GSMP5
  3250.     MOV    BX,GDDHANDLE
  3251.     MOV    AH,3EH
  3252.     INT    21H
  3253. GSMP5:    MOV    AX,SI
  3254.     POPF
  3255. GSMP1:    RET
  3256. LOAD_SAMPLE ENDP
  3257. ;-----------------------------------------------------------------------------
  3258. GET_FILESIZE PROC NEAR
  3259.     MOV    AX,4202H
  3260.     XOR    CX,CX
  3261.     XOR    DX,DX
  3262.     INT    21H
  3263.     PUSH    AX
  3264.     MOV    AX,4200H
  3265.     XOR    CX,CX
  3266.     XOR    DX,DX
  3267.     INT    21H
  3268.     POP    AX
  3269.     RET
  3270. GET_FILESIZE ENDP
  3271. ;=============================================================================
  3272. ; LOAD CONFIG DATA (PARSER)
  3273. ; IN: CX=0C242H, DS:BX= POINTER TO PARAM-BLOCK
  3274. ;
  3275. ; PARAM-BLOCK:     + 0 BASE PORT        210H-280H, 388H, ETC.
  3276. ;                  + 2 DMA NUMBER        0-7
  3277. ;                  + 3 IRQ NUMBER        0-15
  3278. ;        + 4 SAMPLE RATE        10000-44100
  3279. ;               + 6 INTERNAL TYPE       0,1,2,3,... (if necessary)
  3280. ;        + 7 INTERRUPT TYPE      0,1 (realtime clock, timer)
  3281. ;               + 8 STARTING POSITION   0-127
  3282. ;               + 9 LOOP POSITION    0-127,128
  3283. ;               +10 SONG MODUS        0-3
  3284. ;               +11 START MASTER VOLUME 0-255
  3285. ;        +12 START MUSIC VOLUME    0-255
  3286. ;               +13 START FX VOLUME     0-255
  3287. ;-----------------------------------------------------------------------------
  3288. CONFIG_INIT PROC NEAR
  3289.     MOV    DX,DS
  3290.     MOV    AX,CS
  3291.     MOV    DS,AX
  3292.     MOV    WORD PTR HOLD70+2,AX
  3293.     MOV    WORD PTR HOLDSB+2,AX
  3294.     CMP    CX,0C242H
  3295.     JNE    SHORT NORMAL_CONFIG
  3296.     MOV    ES,DX
  3297.     MOV    AX,ES:[BX]
  3298.     ADD    AL,4
  3299.     MOV    SBP_MIXERI,AX
  3300.     INC    AX
  3301.     MOV    SBP_MIXERD,AX
  3302.     INC    AX
  3303.     MOV    SB_RESET,AX
  3304.     ADD    AX,4
  3305.     MOV    SB_READ,AX
  3306.     ADD    AX,2
  3307.     MOV    SB_WRITE,AX
  3308.     ADD    AX,2
  3309.     MOV    SB_RSTAT,AX
  3310.     MOV    AL,ES:[BX+2]
  3311.     AND    AL,7
  3312.     MOV    DMA_CHANNEL,AL
  3313.     MOV    AL,ES:[BX+3]
  3314.     AND    AL,15
  3315.     MOV    IRQ_NUMBER,AL
  3316.     MOV    AX,ES:[BX+4]
  3317.     MOV    SAMPLE_RATE,AX
  3318.     MOV    AL,ES:[BX+6]
  3319.     AND     AL,1
  3320.     INC    AL
  3321.     MOV     SB_TYP,AL
  3322.     MOV    AL,ES:[BX+7]
  3323.     AND     AL,1
  3324.     MOV     SYSTEM,AL
  3325.     MOV    AL,ES:[BX+8]
  3326.     AND    AL,127
  3327.     MOV    SONG_START,AL
  3328.     MOV    AL,ES:[BX+9]
  3329.     MOV    SONG_LOOP,AL
  3330.     MOV    AL,ES:[BX+10]
  3331.     AND     AL,3
  3332.     MOV    SB_MODUS,AL
  3333.     MOV    AL,ES:[BX+11]
  3334.     MOV    BX,ES:[BX+12]
  3335.     CALL    SET_VOLUME
  3336.     JMP    CONT_CONFIG
  3337. NORMAL_CONFIG:
  3338.     MOV     DX,OFFSET CONFIG_NAME
  3339.     MOV     AH,3DH
  3340.     MOV     AL,80H
  3341.     INT     21H
  3342.     JC      GCFG1
  3343.     MOV     GDDHANDLE,AX
  3344. LCFG1:  XOR     SI,SI
  3345.     MOV     DX,OFFSET QUEUE_BUFFER
  3346. LCFG2:  MOV     AH,3FH
  3347.     MOV     BX,GDDHANDLE
  3348.     MOV     CX,1
  3349.     INT     21H
  3350.     JC      GCFG2
  3351.     OR      AX,AX
  3352.     JZ      GCFG2
  3353.     MOV     DI,DX
  3354.     CMP     BYTE PTR [DI],0AH
  3355.     JE      SHORT GCFG6
  3356.     INC     DX
  3357.     INC     SI
  3358.     CMP     SI,256
  3359.     JB      LCFG2
  3360. GCFG6:  MOV     BX,OFFSET CFG_TEXT1
  3361.     CALL    SEEK_LINE
  3362.     JNC     SHORT GCFG3
  3363.     LODSB
  3364.     AND     AL,7
  3365.     MOV    SB_TYP,AL
  3366.     JMP     LCFG1
  3367. GCFG3:  MOV     BX,OFFSET CFG_TEXT2
  3368.     CALL    SEEK_LINE
  3369.     JNC     SHORT GCFG4
  3370.     LODSB
  3371.     AND    AL,1
  3372.     MOV    CD_MIXER,AL
  3373.     LODSB
  3374.     AND     AL,3
  3375.     MOV    SB_MODUS,AL
  3376.     JMP     LCFG1
  3377. GCFG4:  MOV     BX,OFFSET CFG_TEXT3
  3378.     CALL    SEEK_LINE
  3379.     JNC     SHORT GCFG5
  3380.     INC    SI
  3381.     LODSB
  3382.     DEC    AL
  3383.     AND    AL,7
  3384.     INC    AL
  3385.     SHL    AL,4
  3386.     MOV    AH,2
  3387.     ADD    AL,4
  3388.     MOV    SBP_MIXERI,AX
  3389.     INC    AX
  3390.     MOV    SBP_MIXERD,AX
  3391.     INC    AX
  3392.     MOV    SB_RESET,AX
  3393.     ADD    AX,4
  3394.     MOV    SB_READ,AX
  3395.     ADD    AX,2
  3396.     MOV    SB_WRITE,AX
  3397.     ADD    AX,2
  3398.     MOV    SB_RSTAT,AX
  3399.     JMP     LCFG1
  3400. GCFG5:  MOV     BX,OFFSET CFG_TEXT4
  3401.     CALL    SEEK_LINE
  3402.     JNC     SHORT GCFG7
  3403.     LODSW
  3404.     AND     AL,1
  3405.     AND    AH,7
  3406.     MOV    BH,AH
  3407.     MOV    BL,10
  3408.     MUL    BL
  3409.     ADD    AL,BH
  3410.     MOV    IRQ_NUMBER,AL
  3411.     JMP    LCFG1
  3412. GCFG7:  MOV     BX,OFFSET CFG_TEXT5
  3413.     CALL    SEEK_LINE
  3414.     JNC     SHORT GCFG8
  3415.     LODSB
  3416.     AND    AL,3
  3417.     MOV    DMA_CHANNEL,AL
  3418.     JMP    LCFG1
  3419. GCFG8:    MOV    BX,OFFSET CFG_TEXT6
  3420.     CALL    SEEK_LINE
  3421.     JNC    SHORT GCFG9
  3422.     XOR    BX,BX
  3423.     MOV    CX,5
  3424. LCFG3:    MOV    AX,BX
  3425.     MOV    DX,10
  3426.     MUL    DX
  3427.     MOV    BX,AX
  3428.     LODSB
  3429.     AND    AL,0FH
  3430.     XOR    AH,AH
  3431.     ADD    BX,AX
  3432.     LOOP    LCFG3
  3433.     MOV    SAMPLE_RATE,BX
  3434.     JMP     LCFG1
  3435. GCFG9:    MOV     BX,OFFSET CFG_TEXT7
  3436.     CALL    SEEK_LINE
  3437.     JNC     LCFG1
  3438.     LODSB
  3439.     AND     AL,1
  3440.     MOV     SYSTEM,AL
  3441.     JMP     LCFG1
  3442. GCFG2:  MOV     BX,GDDHANDLE
  3443.     MOV     AH,3EH
  3444.     INT     21H
  3445. CONT_CONFIG:
  3446. GCFG1:  RET
  3447. CONFIG_INIT ENDP
  3448. ;-----------------------------------------------------------------------------
  3449. SEEK_LINE PROC NEAR
  3450.     CLD
  3451.     MOV     SI,OFFSET QUEUE_BUFFER
  3452. LSKL1:  PUSH    BX
  3453. LSKL2:  CMP     BYTE PTR [BX],0
  3454.     JE      SHORT GSKL1
  3455.     CMP     SI,DX
  3456.     JAE     SHORT GSKL2
  3457.     LODSB
  3458.     CMP     AL,[BX]
  3459.     JNE     SHORT GSKL3
  3460.     INC     BX      
  3461.     JMP     LSKL2
  3462. GSKL3:  POP     BX
  3463.     JMP     LSKL1
  3464. GSKL2:  POP     BX
  3465.     CLC
  3466.     RET
  3467. GSKL1:  POP     BX
  3468.     STC
  3469.     RET
  3470. SEEK_LINE ENDP
  3471. ;=============================================================================
  3472.  
  3473.  
  3474. ;=============================================================================
  3475. PLAY_MUSIC PROC NEAR
  3476.     PUSH    CS
  3477.     POP    DS
  3478.     MOV    MOD_STAT,0        ;DEACTIVATE IRQ-HANDLING
  3479.     CALL    DSP_RESET
  3480.     JC    GPM1
  3481.     CALL    MAKE_MIXMUL_VOLUMETABLE
  3482.     CALL    IRQ_INIT
  3483.     XOR    EDX,EDX
  3484.     MOV    EAX,1000000
  3485.     MOVZX    EBX,SAMPLE_RATE
  3486.     MOV    CL,SBPRO_FLAG
  3487.     DIV    EBX
  3488.     SHR    AL,CL
  3489.     NEG    AL
  3490.     MOV    DMA_RATE,AL
  3491.     XOR    EDX,EDX
  3492.     MOV    EAX,369E9400H        ;1,193,180 * 300H FOR FREQ CALCS
  3493.     DIV    EBX
  3494.     MOV    MAINFREQ,EAX
  3495.     MOV    AX,BX
  3496.     XOR    DX,DX
  3497.     MOV    BX,50            ;AMIGA TIMING IS 50HZ (SCREEN-REFRESH)
  3498.     DIV    BX
  3499.     SHL    AX,CL
  3500.     MOV    DMA_CX,AX        ;# OF BYTE/CYCLE (434 FOR 22222 HZ)
  3501.     SHL    AX,2            ;4 TIMES FORWARD
  3502.     MOV    DMA_MORE,AX
  3503.     SHL    AX,2            ;16 TIMES MAXIMUM (6944 FOR 22222 HZ)
  3504.     SHR    AX,CL
  3505.     SUB    AH,CL
  3506.     SUB    AH,CL
  3507.     MOV    DMA_MAX,AX
  3508.     MOV    AX,DMA_OFFSET
  3509.     MOV    DMA_PTR,AX
  3510.     MOV    DMA_NEWPTR,AX
  3511.     MOV    AL,125
  3512.     CALL    Go_SetBPM
  3513.     MOV    BPM_COUNT,0
  3514.     MOV    MT_SPEED,6        ;DEFAULT PROTRACKER SPEED
  3515.     XOR    AX,AX
  3516.     MOV    MT_COUNTER,AL        ;RESET PROTRACKER VARIABLES
  3517.     MOV    MT_PATTERNPOS,AX
  3518.     MOV    DL,SONG_START
  3519.     MOV    MT_SONGPOS,DL
  3520.     MOV    MT_PATTDELAYTIME2,AL
  3521.     MOV    MT_PATTDELAYTIME,AL
  3522.     MOV    MT_PBREAKFLAG,AL
  3523.     MOV    MT_PBREAKPOS,AL
  3524.     MOV    MT_POSJUMPFLAG,AL
  3525.     MOV    MT_LOWMASK,0FFH
  3526.     MOV    CX,43*8/2
  3527.     CLD
  3528.     PUSH    DS
  3529.     POP    ES
  3530.     MOV    DI,OFFSET NOTE
  3531.     REP STOSW
  3532.     INC    AL
  3533.     MOV    CX,MAX_CHAN_NUMB
  3534.     MOV    DI,OFFSET TONEPORTDIREC
  3535.     REP STOSB
  3536.     MOV    BYTE PTR SELFN1+2,2
  3537.     MOV    BYTE PTR SELFN2+2,2
  3538.     MOV    BYTE PTR SELFN3+2,2
  3539.     MOV    BYTE PTR SELFN4+2,2
  3540.     TEST    SBPRO_FLAG,1
  3541.     JZ    SHORT GPM2
  3542.     MOV    BYTE PTR SELFN1+2,4
  3543.     MOV    BYTE PTR SELFN2+2,4
  3544.     MOV    BYTE PTR SELFN3+2,4
  3545.     MOV    BYTE PTR SELFN4+2,4
  3546. GPM2:    MOV    CX,3            ;PRECALCULATE SAMPLE DATA FOR INIT
  3547. LPM1:    PUSH    CX
  3548.     CALL    CONTROL_CHANNELS
  3549.     CALL    MIXUP_CHANNELS
  3550.     POP    CX
  3551.     LOOP    LPM1
  3552.     MOV    AH,DMA_RATE        ;SET SB-SAMPLERATE
  3553.     CALL    DSP_RATE
  3554.     MOV    DX,DMA_SEG        ;INITIALIZE DMA
  3555.     MOV    BX,DMA_OFFSET
  3556.     MOV    CX,DMA_MAX
  3557.     CALL    DMA_INIT
  3558.     MOV    MOD_STAT,1        ;ACTIVATE IRQ-HANDLING
  3559.     CLC
  3560. GPM1:    RET
  3561. PLAY_MUSIC ENDP
  3562. ;-----------------------------------------------------------------------------
  3563. STOP_MUSIC PROC NEAR
  3564.     PUSH    CS
  3565.     POP    DS
  3566.     MOV    MOD_STAT,0
  3567.     CALL    DSP_RESET
  3568.     CALL    IRQ_INIT
  3569.     MOV    IRQCOUNT,56
  3570.     RET
  3571. STOP_MUSIC ENDP
  3572. ;-----------------------------------------------------------------------------
  3573. END_MUSIC PROC NEAR
  3574.     PUSH    CS
  3575.     POP    DS
  3576.     CMP    LOADMOD_FLAG,0
  3577.     JNE    SHORT GENM1
  3578.     CALL    FREE_TMEM
  3579. GENM1:    CALL    FREE_DMEM
  3580.     RET
  3581. END_MUSIC ENDP
  3582. ;-----------------------------------------------------------------------------
  3583. GET_SONGMOD PROC NEAR
  3584.     MOV    AL,CS:SB_MODUS
  3585.     RET
  3586. GET_SONGMOD ENDP
  3587. ;-----------------------------------------------------------------------------
  3588. SET_SONGMOD PROC NEAR
  3589.     AND    AL,3
  3590.     MOV    CS:SB_MODUS,AL
  3591.     CMP    CS:SBPRO_FLAG,1
  3592.     JNE    SHORT GSNG1
  3593.     CMP    CS:CD_MIXER,0
  3594.     JE    SHORT GSNG1
  3595.     PUSH    AX DX
  3596.     XOR    AH,AH
  3597.     TEST    AL,2
  3598.     JNZ    SHORT GSNG2
  3599.     MOV    AH,CS:MUSIC_VOL
  3600. GSNG2:    MOV    DX,CS:SBP_MIXERI
  3601.     MOV    AL,28H
  3602.     OUT    DX,AL
  3603.     INC    DX
  3604.     MOV    AL,AH            ;SET CD VOLUME LEFT
  3605.     AND    AL,0F0H
  3606.     SHR    AH,4
  3607.     OR    AL,AH            ;SET CD VOLUME RIGHT
  3608.     OUT    DX,AL
  3609.     POP    DX AX
  3610. GSNG1:    RET
  3611. SET_SONGMOD ENDP
  3612. ;-----------------------------------------------------------------------------
  3613. GET_SONGPOSITION PROC NEAR
  3614.     MOV    AL,CS:MT_SONGPOS
  3615.     RET
  3616. GET_SONGPOSITION ENDP
  3617. ;-----------------------------------------------------------------------------
  3618. SET_SONGPOSITION PROC NEAR
  3619.     PUSH    BX
  3620.     AND    AL,7FH
  3621.     MOV    CS:MT_SONGPOS,AL
  3622.     MOV    CS:MT_PATTERNPOS,0
  3623.     XOR    BX,BX
  3624. LSET1:    MOV    CS:[MSEG+BX],0
  3625.     INC    BL
  3626.     INC    BL
  3627.     CMP    BL,2*MAX_CHAN_NUMB
  3628.     JB    LSET1
  3629.     POP    BX
  3630.     RET
  3631. SET_SONGPOSITION ENDP
  3632. ;-----------------------------------------------------------------------------
  3633. SET_SONGLOOP PROC NEAR
  3634.     MOV    CS:SONG_LOOP,AL
  3635.     RET
  3636. SET_SONGLOOP ENDP
  3637. ;-----------------------------------------------------------------------------
  3638. GET_VOLUME PROC NEAR
  3639.     MOV    AL,CS:MASTER_VOLUME    ;0= MIN VOLUME, 255= MAX VOLUME
  3640.     MOV    BL,CS:MUSIC_VOLUME    ;0= MIN VOLUME, 255= MAX VOLUME
  3641.     MOV    BH,CS:FX_VOLUME        ;0= MIN VOLUME, 255= MAX VOLUME
  3642.     RET
  3643. GET_VOLUME ENDP
  3644. ;-----------------------------------------------------------------------------
  3645. SET_VOLUME PROC NEAR
  3646.     MOV    CS:MASTER_VOLUME,AL    ;0= MIN VOLUME, 255= MAX VOLUME
  3647.     MOV    CS:MUSIC_VOLUME,BL    ;0= MIN VOLUME, 255= MAX VOLUME
  3648.     MOV    CS:FX_VOLUME,BH        ;0= MIN VOLUME, 255= MAX VOLUME
  3649.     PUSH    AX DX
  3650.     MOVZX    DX,AL
  3651.     INC    DX
  3652.     PUSH    DX
  3653.     MOVZX    AX,BL
  3654.     MUL    DX
  3655.     MOV    CS:MUSIC_VOL,AH
  3656.     CMP    CS:SBPRO_FLAG,1
  3657.     JNE    SHORT GSTV1
  3658.     CMP    CS:CD_MIXER,0
  3659.     JE    SHORT GSTV1
  3660.     MOV    DX,CS:SBP_MIXERI
  3661.     MOV    AL,28H
  3662.     OUT    DX,AL
  3663.     INC    DX
  3664.     MOV    AL,AH            ;SET CD VOLUME LEFT
  3665.     AND    AL,0F0H
  3666.     SHR    AH,4
  3667.     OR    AL,AH            ;SET CD VOLUME RIGHT
  3668.     OUT    DX,AL
  3669. GSTV1:    POP    DX
  3670.     MOVZX    AX,BH
  3671.     MUL    DX
  3672.     MOV    CS:FX_VOL,AH
  3673.     POP    DX AX
  3674.     RET
  3675. SET_VOLUME ENDP
  3676. ;-----------------------------------------------------------------------------
  3677. SET_LOADMOD_FLAG PROC NEAR
  3678.     AND    AL,1
  3679.     MOV    CS:LOADMOD_FLAG,AL    ;0= NORMAL, 1= CD PLAYER MODUS
  3680.     RET
  3681. SET_LOADMOD_FLAG ENDP
  3682. ;-----------------------------------------------------------------------------
  3683. SET_SAMPLERATE PROC NEAR
  3684.     CMP    AX,10000
  3685.     JAE    SHORT GSSR1
  3686.     MOV    AX,10000
  3687. GSSR1:    CMP    AX,22222
  3688.     JBE    SHORT GSSR2
  3689.     MOV    AX,22222
  3690. GSSR2:    MOV    CS:SAMPLE_RATE,AX    ;BEST BETWEEN 10000 - 22222 Hz
  3691.     RET
  3692. SET_SAMPLERATE ENDP
  3693. ;-----------------------------------------------------------------------------
  3694. SET_IRQ_RATE PROC NEAR
  3695.     PUSH    CS
  3696.     POP    DS
  3697.     MOV    BPM_RATE,AX
  3698.     MOV    AX,BPM_VALUE
  3699.     CALL    Go_SetBPM
  3700.     RET
  3701. SET_IRQ_RATE ENDP
  3702. ;-----------------------------------------------------------------------------
  3703. ; STARTET SAMPLE AUSGABE
  3704. ; BX= SAMPLE-HANDLE, CX= SAMPLERATE, AL= PANNING: 0= LEFT, 255=RIGHT
  3705. ;-----------------------------------------------------------------------------
  3706. PLAY_SAMPLE PROC NEAR
  3707.     PUSH    CS
  3708.     POP    DS
  3709.     TEST    SB_MODUS,1
  3710.     JNZ    GPSMP1
  3711.     CMP    EMS_SEG,0
  3712.     JE    GPSMP1
  3713.     PUSH    AX
  3714.     MOVZX    EAX,CX    
  3715.     SHL    EAX,8
  3716.     MOVZX    ECX,SAMPLE_RATE
  3717.     XOR    EDX,EDX
  3718.     DIV    ECX
  3719.     POP    DX
  3720.     OR    AX,AX
  3721.     JZ    GPSMP1
  3722.     CMP    SBPRO_FLAG,1
  3723.     JE    SHORT GPSMP2
  3724.     CMP    SAM_SEG1,0
  3725.     JE    SHORT GGSMP1
  3726.     CMP    SAM_SEG2,0
  3727.     JE    GGSMP2
  3728.     JMP    SHORT GPSMP3
  3729. GPSMP2:    OR    DL,DL
  3730.     JS    SHORT GPSMP4
  3731.     CMP    SAM_SEG1,0
  3732.     JE    SHORT GGSMP1
  3733.     CMP    SAM_SEG2,0
  3734.     JE    SHORT GGSMP2
  3735.     CMP    SAM_SEG3,0
  3736.     JE    GGSMP3
  3737.     CMP    SAM_SEG4,0
  3738.     JE    GGSMP4
  3739. GPSMP3:    XOR    SAM_FLAG1,1
  3740.     TEST    SAM_FLAG1,1
  3741.     JZ    SHORT GGSMP1
  3742.     JMP    SHORT GGSMP2
  3743. GPSMP4:    CMP    SAM_SEG3,0
  3744.     JE    SHORT GGSMP3
  3745.     CMP    SAM_SEG4,0
  3746.     JE    GGSMP4
  3747.     CMP    SAM_SEG1,0
  3748.     JE    SHORT GGSMP1
  3749.     CMP    SAM_SEG2,0
  3750.     JE    SHORT GGSMP2
  3751.     XOR    SAM_FLAG2,1
  3752.     TEST    SAM_FLAG2,1
  3753.     JZ    SHORT GGSMP3
  3754.     JMP    SHORT GGSMP4
  3755. GGSMP1:    CLI                ;LEFT CHANNEL SAMPLE1
  3756.     MOV    SAM_FRQ1,AX
  3757.     MOV    AX,EMS_SEG
  3758.     MOV    SAM_SEG1,AX
  3759.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3760.     SHL    EAX,4
  3761.     MOV    SAM_OFS1,EAX
  3762.     MOV    AX,[SAMPLE_BIG+BX]
  3763.     MOV    SAM_MAX1,AX
  3764.     MOV    SAM_OFL1,0
  3765.     STI
  3766. GPSMP1:    RET
  3767. GGSMP2:    CLI                ;LEFT CHANNEL SAMPLE2
  3768.     MOV    SAM_FRQ2,AX
  3769.     MOV    AX,EMS_SEG
  3770.     MOV    SAM_SEG2,AX
  3771.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3772.     SHL    EAX,4
  3773.     MOV    SAM_OFS2,EAX
  3774.     MOV    AX,[SAMPLE_BIG+BX]
  3775.     MOV    SAM_MAX2,AX
  3776.     MOV    SAM_OFL2,0
  3777.     STI
  3778.     RET
  3779. GGSMP3:    CLI                ;RIGHT CHANNEL SAMPLE3
  3780.     MOV    SAM_FRQ3,AX
  3781.     MOV    AX,EMS_SEG
  3782.     MOV    SAM_SEG3,AX
  3783.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3784.     SHL    EAX,4
  3785.     MOV    SAM_OFS3,EAX
  3786.     MOV    AX,[SAMPLE_BIG+BX]
  3787.     MOV    SAM_MAX3,AX
  3788.     MOV    SAM_OFL3,0
  3789.     STI
  3790.     RET
  3791. GGSMP4:    CLI                ;RIGHT CHANNEL SAMPLE4
  3792.     MOV    SAM_FRQ4,AX
  3793.     MOV    AX,EMS_SEG
  3794.     MOV    SAM_SEG4,AX
  3795.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3796.     SHL    EAX,4
  3797.     MOV    SAM_OFS4,EAX
  3798.     MOV    AX,[SAMPLE_BIG+BX]
  3799.     MOV    SAM_MAX4,AX
  3800.     MOV    SAM_OFL4,0
  3801.     STI
  3802.     RET
  3803. PLAY_SAMPLE ENDP
  3804. ;-----------------------------------------------------------------------------
  3805. END_SAMPLE PROC NEAR
  3806.     PUSH    CS
  3807.     POP    DS
  3808.     MOV    SAM_SEG1,0
  3809.     MOV    SAM_SEG2,0
  3810.     MOV    SAM_SEG3,0
  3811.     MOV    SAM_SEG4,0
  3812.     CMP    EMS_SEG,0
  3813.     JE    SHORT GEMP1
  3814.     MOV    AH,45H
  3815.     MOV    DX,EMS_HANDLE
  3816.     INT    67H
  3817.     MOV    EMS_SEG,0
  3818. GEMP1:    RET
  3819. END_SAMPLE ENDP
  3820. ;=============================================================================
  3821.  
  3822.  
  3823. IF COM_OR_OBJ
  3824. ;=============================================================================
  3825. MAIN_CONT PROC NEAR
  3826.     PUSH    BP DS CS ES
  3827.     POP    DS
  3828.     SHL    DI,2
  3829.     ADD    DI,0100H
  3830.     CALL    DI            ;FAR CALL
  3831.     SETC    DL
  3832.     XOR    DH,DH
  3833.     POP    DS BP            ;BP IS ABSOLUTELY IMPORTANT FOR C
  3834.     RETF
  3835. MAIN_CONT ENDP
  3836. ;=============================================================================
  3837.  
  3838. ELSE
  3839. ;=============================================================================
  3840. ;
  3841. ; MAIN ROUTINE
  3842. ;
  3843. ;=============================================================================
  3844. MAIN_CONT PROC NEAR
  3845.     MOV    AX,CS            ;DS setzen
  3846.     MOV    DS,AX
  3847.     MOV     PROG_START_SEG,ES       ;PROGRAMMANFANG
  3848.     MOV     AX,SS                   ;UND -ENDE MERKEN
  3849.     MOV     BX,OFFSET PROG_END
  3850.     ADD     BX,STACKLENGTH
  3851.     MOV     SP,BX
  3852.     SHR     BX,4
  3853.     INC     BX
  3854.     ADD     AX,BX
  3855.     MOV     PROG_END_SEG,AX
  3856.     XOR    BX,BX
  3857. GL1:    MOV    AL,ES:[82H+BX]
  3858.     OR    AL,AL
  3859.     JZ    SHORT GL2
  3860.     CMP    AL,20H
  3861.     JE    SHORT GL2
  3862.     CMP    AL,0DH
  3863.     JE    SHORT GL2
  3864.     MOV    [MOD_NAME+BX],AL
  3865.     INC    BX
  3866.     CMP    BX,40H
  3867.     JB    GL1
  3868. GL2:    OR    BX,BX
  3869.     JZ    GMEND
  3870.     XOR    AL,AL
  3871.     MOV    [MOD_NAME+BX],0
  3872.     CALL    FREE_MEM
  3873.     MOV    VAR_BUFSEG,0
  3874. ;-----------------------------------------------------------------------------
  3875. ; INITIALIZING & STARTING
  3876. ;    MOV    AX,22222        ;SET MAXIMUM SAMPLERATE
  3877. ;    CALL    SET_SAMPLERATE
  3878. ;    MOV    AL,255            ;SET MAXIMUM VOLUME
  3879. ;    MOV    BL,AL
  3880. ;    MOV    BH,AL
  3881. ;    CALL    SET_VOLUME
  3882.     CALL    CONFIG_INIT        ;GET CONFIG
  3883.     MOV    DX,OFFSET MOD_NAME    ;FIRST, TRY LOADING
  3884.     CALL    LOAD_MOD
  3885.     JNC    SHORT GM1
  3886.     MOV    AH,9
  3887.     MOV    DX,OFFSET ERROR1_TEXT
  3888.     INT    21H
  3889.     JMP    SHORT GM4
  3890. GM1:    MOV    DX,OFFSET SAMPLE_NAME    ;GET SAMPLE
  3891.     MOV    CL,80H            ;PC-SAMPLE
  3892.     CALL    LOAD_SAMPLE
  3893.     JNC    SHORT GM2
  3894.     MOV    AH,9
  3895.     MOV    DX,OFFSET ERROR2_TEXT
  3896.     INT    21H
  3897. GM2:    CALL    PLAY_MUSIC        ;TRY STARTING
  3898.     JNC    SHORT GM3
  3899.     MOV    AH,9
  3900.     MOV    DX,OFFSET ERROR3_TEXT
  3901.     INT    21H
  3902.     JMP    SHORT GM4
  3903. ;-----------------------------------------------------------------------------
  3904. ; THIS COULD BE THE MAIN ROUTINE
  3905. GM3:    MOV    AH,9
  3906.     MOV    DX,OFFSET OUT_TEXT
  3907.     INT    21H
  3908. LM1:    XOR    AH,AH
  3909.     INT    16H
  3910.     CMP    AL,27
  3911.     JE    SHORT GM5
  3912.     CMP    AL,"+"
  3913.     JNE    SHORT G1
  3914.     CALL    GET_VOLUME
  3915.     INC    AL
  3916.     CALL    SET_VOLUME
  3917.     JMP    LM1
  3918. G1:    CMP    AL,"-"
  3919.     JNE    SHORT G2
  3920.     CALL    GET_VOLUME
  3921.     DEC    AL
  3922.     CALL    SET_VOLUME
  3923.     JMP    LM1
  3924. G2:    CMP    AL,"9"
  3925.     JNE    SHORT G3
  3926.     MOV    AL,0
  3927.     CALL    SET_SONGLOOP
  3928.     JMP    LM1
  3929. G3:    CMP    AL,"0"
  3930.     JNE    SHORT G4
  3931.     INC    SB_MODUS
  3932.     MOV    AL,SB_MODUS
  3933.     CALL    SET_SONGMOD
  3934.     JMP    LM1
  3935. G4:    CMP    AL,"1"
  3936.     JNE    LM1
  3937.     ADD    PAN_FX,20H
  3938.     MOV    AL,PAN_FX        ;PANNING
  3939.     XOR    BX,BX            ;HANDLE
  3940.     MOV    CX,22222        ;FREQUENCE
  3941.     CALL    PLAY_SAMPLE
  3942.     JMP    LM1
  3943. ;-----------------------------------------------------------------------------
  3944. ; CUTTING OFF
  3945. GM5:    CALL    STOP_MUSIC        ;STOP MUSIC
  3946. GM4:    CALL    END_SAMPLE        ;UNLOAD SAMPLES
  3947.     CALL    END_MUSIC        ;UNLOAD MUSIC
  3948. GMEND:    MOV     AX,4C00H                ;BEENDEN NACH DOS
  3949.     INT     21H
  3950. MAIN_CONT ENDP
  3951. ;=============================================================================
  3952. ENDIF
  3953.  
  3954. ;=============================================================================
  3955. RASTER_COL PROC NEAR
  3956.     MOV    DX,03DAH
  3957.     IN    AL,DX
  3958.     MOV     DX,03C0H                ;OVERSCAN AENDERN        
  3959.     MOV     AL,31H                  ;REGISTER 11H
  3960.     OUT     DX,AL                   ;BILDSCHIRM AUS
  3961.     MOV     AL,AH                   ;WERT AH IN REGISTER (DAC-INDEX)
  3962.     OUT     DX,AL
  3963.     RET
  3964. RASTER_COL ENDP
  3965. ;=============================================================================
  3966. CODE_SEG1 ENDS
  3967.  
  3968. END _MAIN1